Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bafb282d authored by Konstantin Khlebnikov's avatar Konstantin Khlebnikov Committed by Linus Torvalds
Browse files

c/r: prctl: update prctl_set_mm_exe_file() after mm->num_exe_file_vmas removal



A fix for commit b32dfe37 ("c/r: prctl: add ability to set new
mm_struct::exe_file").

After removing mm->num_exe_file_vmas kernel keeps mm->exe_file until
final mmput(), it never becomes NULL while task is alive.

We can check for other mapped files in mm instead of checking
mm->num_exe_file_vmas, and mark mm with flag MMF_EXE_FILE_CHANGED in
order to forbid second changing of mm->exe_file.

Signed-off-by: default avatarKonstantin Khlebnikov <khlebnikov@openvz.org>
Reviewed-by: default avatarCyrill 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 6305902c
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -439,6 +439,7 @@ extern int get_dumpable(struct mm_struct *mm);
					/* leave room for more dump flags */
					/* leave room for more dump flags */
#define MMF_VM_MERGEABLE	16	/* KSM may merge identical pages */
#define MMF_VM_MERGEABLE	16	/* KSM may merge identical pages */
#define MMF_VM_HUGEPAGE		17	/* set when VM_HUGEPAGE is set on vma */
#define MMF_VM_HUGEPAGE		17	/* set when VM_HUGEPAGE is set on vma */
#define MMF_EXE_FILE_CHANGED	18	/* see prctl_set_mm_exe_file() */


#define MMF_INIT_MASK		(MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK)
#define MMF_INIT_MASK		(MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK)


+19 −12
Original line number Original line Diff line number Diff line
@@ -1796,17 +1796,11 @@ static bool vma_flags_mismatch(struct vm_area_struct *vma,


static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
{
{
	struct vm_area_struct *vma;
	struct file *exe_file;
	struct file *exe_file;
	struct dentry *dentry;
	struct dentry *dentry;
	int err;
	int err;


	/*
	 * Setting new mm::exe_file is only allowed when no VM_EXECUTABLE vma's
	 * remain. So perform a quick test first.
	 */
	if (mm->num_exe_file_vmas)
		return -EBUSY;

	exe_file = fget(fd);
	exe_file = fget(fd);
	if (!exe_file)
	if (!exe_file)
		return -EBADF;
		return -EBADF;
@@ -1827,17 +1821,30 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
	if (err)
	if (err)
		goto exit;
		goto exit;


	down_write(&mm->mmap_sem);

	/*
	 * Forbid mm->exe_file change if there are mapped other files.
	 */
	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;
	}

	/*
	/*
	 * The symlink can be changed only once, just to disallow arbitrary
	 * The symlink can be changed only once, just to disallow arbitrary
	 * transitions malicious software might bring in. This means one
	 * transitions malicious software might bring in. This means one
	 * could make a snapshot over all processes running and monitor
	 * could make a snapshot over all processes running and monitor
	 * /proc/pid/exe changes to notice unusual activity if needed.
	 * /proc/pid/exe changes to notice unusual activity if needed.
	 */
	 */
	down_write(&mm->mmap_sem);
	err = -EPERM;
	if (likely(!mm->exe_file))
	if (test_and_set_bit(MMF_EXE_FILE_CHANGED, &mm->flags))
		goto exit_unlock;

	set_mm_exe_file(mm, exe_file);
	set_mm_exe_file(mm, exe_file);
	else
exit_unlock:
		err = -EBUSY;
	up_write(&mm->mmap_sem);
	up_write(&mm->mmap_sem);


exit:
exit: