| From foo@baz Sat Jul 28 12:29:48 CEST 2018 |
| From: Chintan Pandya <cpandya@codeaurora.org> |
| Date: Thu, 7 Jun 2018 17:06:50 -0700 |
| Subject: mm: vmalloc: avoid racy handling of debugobjects in vunmap |
| |
| From: Chintan Pandya <cpandya@codeaurora.org> |
| |
| [ Upstream commit f3c01d2f3ade6790db67f80fef60df84424f8964 ] |
| |
| 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> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| mm/vmalloc.c | 3 ++- |
| 1 file changed, 2 insertions(+), 1 deletion(-) |
| |
| --- a/mm/vmalloc.c |
| +++ b/mm/vmalloc.c |
| @@ -1440,7 +1440,7 @@ static void __vunmap(const void *addr, i |
| 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); |
| @@ -1450,6 +1450,7 @@ static void __vunmap(const void *addr, i |
| debug_check_no_locks_freed(addr, area->size); |
| debug_check_no_obj_freed(addr, area->size); |
| |
| + remove_vm_area(addr); |
| if (deallocate_pages) { |
| int i; |
| |