Re: [patch 2/6] mm: fix vma_is_anonymous() false-positives

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Jul 21, 2018 at 3:34 PM Linus Torvalds
<torvalds@xxxxxxxxxxxxxxxxxxxx> wrote:
>
> But I basically think that with those patches in place, we can:
>
>  - make vm_area_alloc() just default vm_ops to &dummy_vm_ops
>
>  - just take the part of Kirill's patch that does
>
>                 vma->vm_ops = &anon_vm_ops;
>
>    and instead of '&anon_vm_ops', set it to NULL.

IOW, Kirill's patch now just boils down to the attached trial patch.

I will *not* be committing this last patch, I think it needs more
testing and ack's. And honestly, authorship should go to Kirill if
he's ok with it, because all the basic "these are the anonymous vma's"
places came from Kirill's patch and work.

But it works for me, and I did commit and push out the parts that were
just trivial cleanups with no actual semantic changes.

Comments?

              Linus
 drivers/char/mem.c | 1 +
 fs/exec.c          | 1 +
 kernel/fork.c      | 2 ++
 mm/mmap.c          | 4 +++-
 mm/nommu.c         | 3 ++-
 5 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index ffeb60d3434c..0d4c185c2f6c 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -708,6 +708,7 @@ static int mmap_zero(struct file *file, struct vm_area_struct *vma)
 #endif
 	if (vma->vm_flags & VM_SHARED)
 		return shmem_zero_setup(vma);
+	vma->vm_ops = NULL;
 	return 0;
 }
 
diff --git a/fs/exec.c b/fs/exec.c
index 72e961a62adb..b0c6efce324a 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -293,6 +293,7 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
 	bprm->vma = vma = vm_area_alloc(mm);
 	if (!vma)
 		return -ENOMEM;
+	vma->vm_ops = NULL;
 
 	if (down_write_killable(&mm->mmap_sem)) {
 		err = -EINTR;
diff --git a/kernel/fork.c b/kernel/fork.c
index a191c05e757d..dd50b5220713 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -310,11 +310,13 @@ static struct kmem_cache *mm_cachep;
 
 struct vm_area_struct *vm_area_alloc(struct mm_struct *mm)
 {
+	static const struct vm_operations_struct dummy_vm_ops = {};
 	struct vm_area_struct *vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
 
 	if (vma) {
 		vma->vm_mm = mm;
 		INIT_LIST_HEAD(&vma->anon_vma_chain);
+		vma->vm_ops = &dummy_vm_ops;
 	}
 	return vma;
 }
diff --git a/mm/mmap.c b/mm/mmap.c
index ff1944d8d458..b90176eb9e94 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1778,7 +1778,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
 		error = shmem_zero_setup(vma);
 		if (error)
 			goto free_vma;
-	}
+	} else
+		vma->vm_ops = NULL;
 
 	vma_link(mm, vma, prev, rb_link, rb_parent);
 	/* Once vma denies write, undo our temporary denial count */
@@ -2983,6 +2984,7 @@ static int do_brk_flags(unsigned long addr, unsigned long len, unsigned long fla
 		return -ENOMEM;
 	}
 
+	vma->vm_ops = NULL;
 	vma->vm_start = addr;
 	vma->vm_end = addr + len;
 	vma->vm_pgoff = pgoff;
diff --git a/mm/nommu.c b/mm/nommu.c
index 1d22fdbf7d7c..e1f8b7eb5683 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1145,7 +1145,8 @@ static int do_mmap_private(struct vm_area_struct *vma,
 		if (ret < len)
 			memset(base + ret, 0, len - ret);
 
-	}
+	} else
+		vma->vm_ops = NULL;
 
 	return 0;
 

[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux