diff options
| author | Konstantin Khlebnikov <khlebnikov@openvz.org> | 2012-07-11 14:02:11 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-11 16:04:43 -0700 | 
| commit | 4229fb1dc6843c49a14bb098719f8a696cdc44f8 (patch) | |
| tree | b4c8bd028870c42487a168842f43a15d09d4a4d0 /kernel/sys.c | |
| parent | a4e08d001f2e50bb8b3c4eebadcf08e5535f02ee (diff) | |
| download | olio-linux-3.10-4229fb1dc6843c49a14bb098719f8a696cdc44f8.tar.xz olio-linux-3.10-4229fb1dc6843c49a14bb098719f8a696cdc44f8.zip  | |
c/r: prctl: less paranoid prctl_set_mm_exe_file()
"no other files mapped" requirement from my previous patch (c/r: prctl:
update prctl_set_mm_exe_file() after mm->num_exe_file_vmas removal) is too
paranoid, it forbids operation even if there mapped one shared-anon vma.
Let's check that current mm->exe_file already unmapped, in this case
exe_file symlink already outdated and its changing is reasonable.
Plus, this patch fixes exit code in case operation success.
Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org>
Reported-by: Cyrill Gorcunov <gorcunov@openvz.org>
Tested-by: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Matt Helsley <matthltc@us.ibm.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Pavel Emelyanov <xemul@parallels.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.c | 16 | 
1 files changed, 10 insertions, 6 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index e0c8ffc50d7..2d39a84cd85 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1788,7 +1788,6 @@ SYSCALL_DEFINE1(umask, int, mask)  #ifdef CONFIG_CHECKPOINT_RESTORE  static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)  { -	struct vm_area_struct *vma;  	struct file *exe_file;  	struct dentry *dentry;  	int err; @@ -1816,13 +1815,17 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)  	down_write(&mm->mmap_sem);  	/* -	 * Forbid mm->exe_file change if there are mapped other files. +	 * Forbid mm->exe_file change if old file still mapped.  	 */  	err = -EBUSY; -	for (vma = mm->mmap; vma; vma = vma->vm_next) { -		if (vma->vm_file && !path_equal(&vma->vm_file->f_path, -						&exe_file->f_path)) -			goto exit_unlock; +	if (mm->exe_file) { +		struct vm_area_struct *vma; + +		for (vma = mm->mmap; vma; vma = vma->vm_next) +			if (vma->vm_file && +			    path_equal(&vma->vm_file->f_path, +				       &mm->exe_file->f_path)) +				goto exit_unlock;  	}  	/* @@ -1835,6 +1838,7 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)  	if (test_and_set_bit(MMF_EXE_FILE_CHANGED, &mm->flags))  		goto exit_unlock; +	err = 0;  	set_mm_exe_file(mm, exe_file);  exit_unlock:  	up_write(&mm->mmap_sem);  |