summaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorChintan Pandya <cpandya@codeaurora.org>2018-06-08 02:06:50 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-08 02:34:35 +0200
commitf3c01d2f3ade6790db67f80fef60df84424f8964 (patch)
tree4dc429b6075b3ad2759203617c5c2b9a7277f612 /mm
parentmm: vmalloc: clean up vunmap to avoid pgtable ops twice (diff)
downloadlinux-f3c01d2f3ade6790db67f80fef60df84424f8964.tar.xz
linux-f3c01d2f3ade6790db67f80fef60df84424f8964.zip
mm: vmalloc: avoid racy handling of debugobjects in vunmap
Currently, __vunmap flow is, 1) Release the VM area 2) Free the debug objects corresponding to that vm area. This leave some race window open. 1) Release the VM area 1.5) Some other client gets the same vm area 1.6) This client allocates new debug objects on the same vm area 2) Free the debug objects corresponding to this vm area. Here, we actually free 'other' client's debug objects. Fix this by freeing the debug objects first and then releasing the VM area. Link: http://lkml.kernel.org/r/1523961828-9485-2-git-send-email-cpandya@codeaurora.org Signed-off-by: Chintan Pandya <cpandya@codeaurora.org> Reviewed-by: Andrew Morton <akpm@linux-foundation.org> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Byungchul Park <byungchul.park@lge.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Laura Abbott <labbott@redhat.com> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: Wei Yang <richard.weiyang@gmail.com> Cc: Yisheng Xie <xieyisheng1@huawei.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/vmalloc.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 12bd82e6554e..4df66e1abeb1 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1504,7 +1504,7 @@ static void __vunmap(const void *addr, int deallocate_pages)
addr))
return;
- area = remove_vm_area(addr);
+ area = find_vmap_area((unsigned long)addr)->vm;
if (unlikely(!area)) {
WARN(1, KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n",
addr);
@@ -1514,6 +1514,7 @@ static void __vunmap(const void *addr, int deallocate_pages)
debug_check_no_locks_freed(addr, get_vm_area_size(area));
debug_check_no_obj_freed(addr, get_vm_area_size(area));
+ remove_vm_area(addr);
if (deallocate_pages) {
int i;