aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorMarkus Metzger <markus.t.metzger@intel.com>2009-02-11 09:10:27 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-11 09:44:20 -0500
commit9f339e7028e2855717af3193c938f9960ad13b38 (patch)
tree76e0e9181f4ee2b324742d517518e837d5c250bf /mm
parent06eb23b1ba39c61ee5d5faeb42a097635693e370 (diff)
x86, ptrace, mm: fix double-free on race
Ptrace_detach() races with __ptrace_unlink() if the traced task is reaped while detaching. This might cause a double-free of the BTS buffer. Change the ptrace_detach() path to only do the memory accounting in ptrace_bts_detach() and leave the buffer free to ptrace_bts_untrace() which will be called from __ptrace_unlink(). The fix follows a proposal from Oleg Nesterov. Reported-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Markus Metzger <markus.t.metzger@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'mm')
-rw-r--r--mm/mlock.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/mm/mlock.c b/mm/mlock.c
index 028ec482fdd4..2b57f7e60390 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -657,7 +657,7 @@ void *alloc_locked_buffer(size_t size)
657 return buffer; 657 return buffer;
658} 658}
659 659
660void free_locked_buffer(void *buffer, size_t size) 660void release_locked_buffer(void *buffer, size_t size)
661{ 661{
662 unsigned long pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT; 662 unsigned long pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT;
663 663
@@ -667,6 +667,11 @@ void free_locked_buffer(void *buffer, size_t size)
667 current->mm->locked_vm -= pgsz; 667 current->mm->locked_vm -= pgsz;
668 668
669 up_write(&current->mm->mmap_sem); 669 up_write(&current->mm->mmap_sem);
670}
671
672void free_locked_buffer(void *buffer, size_t size)
673{
674 release_locked_buffer(buffer, size);
670 675
671 kfree(buffer); 676 kfree(buffer);
672} 677}