[patch] mremap problems in latest linux kernels

From: var@msu.ru
Date: Fri Jun 02 2000 - 06:01:59 EST


Following patch fixes a problem in `mremap' functionality,
which was detected in latest linux kernels.

System without these changes may be easily locked by user-level
program issuing few `mremap' calls (see some example code below).

The reason and sort of this bug must be clean from patch.

<<<<<<<<<<<<<<<<<
diff -urN linux-2.4.0-test1.orig/mm/mremap.c linux-2.4.0-test1/mm/mremap.c
--- linux-2.4.0-test1.orig/mm/mremap.c Wed Apr 26 20:16:39 2000
+++ linux-2.4.0-test1/mm/mremap.c Fri Jun 2 14:26:36 2000
@@ -144,7 +144,7 @@
                         vmlist_modify_lock(current->mm);
                         insert_vm_struct(current->mm, new_vma);
                         merge_segments(current->mm, new_vma->vm_start, new_vma->vm_end);
- vmlist_modify_unlock(vma->vm_mm);
+ vmlist_modify_unlock(current->mm);
                         do_munmap(current->mm, addr, old_len);
                         current->mm->total_vm += new_len >> PAGE_SHIFT;
                         if (new_vma->vm_flags & VM_LOCKED) {
>>>>>>>>>>>>>>>>>>

Best regards,
Vladimir.

Andrey Slepuhin writes:
> Hi,
>
> We tried to test mremap with new MREMAP_FIXED flag and found
> a strange behaviour: the following small program
>
> ------------- 8< ------------------------------------------
> #include <linux/types.h>
> #include <linux/unistd.h>
> #include <linux/mman.h>
>
> extern void* mmap (
> void* _start, size_t _length, int _prot, int _flags, int _fd, off_t
> _offset
> );
>
> static inline _syscall5 (
> void*, mremap,
> void*, _old_addr,
> size_t, _old_size,
> size_t, _new_size,
> unsigned long, _flags,
> void*, _new_addr
> );
>
> int main ()
> {
> void* p = mmap (NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE |
> MAP_ANON, 0, 0);
> void* p2 = mmap (NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE |
> MAP_ANON, 0, 0);
> mremap (p2, 4096, 4096, MREMAP_MAYMOVE | MREMAP_FIXED, p);
> }
> ------------- 8< ------------------------------------------
>
> hangs hardly and can not be killed. Moreover, this leads to various
> program hangups (e.g. ps also hangs after that). We tested the program
> above with different kernels and found that effect is absolutelty
> stable on SMP kernels from 2.3.99-pre7 and later. First we thought
> that a problem is a sort of SMP race condition, but after debugging
> we found that vmlist_modify_unlock(vma->vm_mm) at line 147 in
> mm/mremap.c
> forces a pagefault (and this became visible due to slab poisoning in
> 2.3.99-pre7).
> And this vmlist_modify_unlock call seems very strange, because
> we cannot find matching vmlist_modify_unlock for
> vmlist_modify_lock(current->mm)
> at line 144. We tried to replace vmlist_modify_unlock(vma->vm_mm) with
> vmlist_modify_unlock(current->mm). After that our program run normally.
> But anyway it is not possible to call vmlist_modify_unlock(vma->vm_mm)
> because vma may be destroyed due to merge_segments() call. And this is
> exactly the case of our program.
> Is a call of vmlist_modify_unlock(vma->vm_mm) really a typo or there
> should be
> another fix for our problem?
>
> Regards,
> Andrey.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Jun 07 2000 - 21:00:14 EST