aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 7879729bd3bd..14222a1699c0 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1628,12 +1628,14 @@ SYSCALL_DEFINE1(umask, int, mask)
1628 return mask; 1628 return mask;
1629} 1629}
1630 1630
1631static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd) 1631static int prctl_set_mm_exe_file_locked(struct mm_struct *mm, unsigned int fd)
1632{ 1632{
1633 struct fd exe; 1633 struct fd exe;
1634 struct inode *inode; 1634 struct inode *inode;
1635 int err; 1635 int err;
1636 1636
1637 VM_BUG_ON(!rwsem_is_locked(&mm->mmap_sem));
1638
1637 exe = fdget(fd); 1639 exe = fdget(fd);
1638 if (!exe.file) 1640 if (!exe.file)
1639 return -EBADF; 1641 return -EBADF;
@@ -1654,8 +1656,6 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
1654 if (err) 1656 if (err)
1655 goto exit; 1657 goto exit;
1656 1658
1657 down_write(&mm->mmap_sem);
1658
1659 /* 1659 /*
1660 * Forbid mm->exe_file change if old file still mapped. 1660 * Forbid mm->exe_file change if old file still mapped.
1661 */ 1661 */
@@ -1667,7 +1667,7 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
1667 if (vma->vm_file && 1667 if (vma->vm_file &&
1668 path_equal(&vma->vm_file->f_path, 1668 path_equal(&vma->vm_file->f_path,
1669 &mm->exe_file->f_path)) 1669 &mm->exe_file->f_path))
1670 goto exit_unlock; 1670 goto exit;
1671 } 1671 }
1672 1672
1673 /* 1673 /*
@@ -1678,13 +1678,10 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
1678 */ 1678 */
1679 err = -EPERM; 1679 err = -EPERM;
1680 if (test_and_set_bit(MMF_EXE_FILE_CHANGED, &mm->flags)) 1680 if (test_and_set_bit(MMF_EXE_FILE_CHANGED, &mm->flags))
1681 goto exit_unlock; 1681 goto exit;
1682 1682
1683 err = 0; 1683 err = 0;
1684 set_mm_exe_file(mm, exe.file); /* this grabs a reference to exe.file */ 1684 set_mm_exe_file(mm, exe.file); /* this grabs a reference to exe.file */
1685exit_unlock:
1686 up_write(&mm->mmap_sem);
1687
1688exit: 1685exit:
1689 fdput(exe); 1686 fdput(exe);
1690 return err; 1687 return err;
@@ -1703,8 +1700,12 @@ static int prctl_set_mm(int opt, unsigned long addr,
1703 if (!capable(CAP_SYS_RESOURCE)) 1700 if (!capable(CAP_SYS_RESOURCE))
1704 return -EPERM; 1701 return -EPERM;
1705 1702
1706 if (opt == PR_SET_MM_EXE_FILE) 1703 if (opt == PR_SET_MM_EXE_FILE) {
1707 return prctl_set_mm_exe_file(mm, (unsigned int)addr); 1704 down_write(&mm->mmap_sem);
1705 error = prctl_set_mm_exe_file_locked(mm, (unsigned int)addr);
1706 up_write(&mm->mmap_sem);
1707 return error;
1708 }
1708 1709
1709 if (addr >= TASK_SIZE || addr < mmap_min_addr) 1710 if (addr >= TASK_SIZE || addr < mmap_min_addr)
1710 return -EINVAL; 1711 return -EINVAL;