aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
authorCyrill Gorcunov <gorcunov@openvz.org>2014-10-09 18:27:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-09 22:25:55 -0400
commit71fe97e185040c5dac3216cd54e186dfa534efa0 (patch)
treeac0583add2420caac983aca6a4a81c53009e00a4 /kernel/sys.c
parent8764b338b37524ab1a78aee527318ebee9762487 (diff)
prctl: PR_SET_MM -- factor out mmap_sem when updating mm::exe_file
Instead of taking mm->mmap_sem inside prctl_set_mm_exe_file() move it out and rename the helper to prctl_set_mm_exe_file_locked(). This will allow to reuse this function in a next patch. Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Cc: Kees Cook <keescook@chromium.org> Cc: Tejun Heo <tj@kernel.org> Cc: Andrew Vagin <avagin@openvz.org> Cc: Eric W. Biederman <ebiederm@xmission.com> Cc: H. Peter Anvin <hpa@zytor.com> Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Cc: Pavel Emelyanov <xemul@parallels.com> Cc: Vasiliy Kulikov <segoon@openwall.com> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Michael Kerrisk <mtk.manpages@gmail.com> Cc: Julien Tinnes <jln@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
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;