summaryrefslogtreecommitdiffstats
path: root/src/vppinfra/linux/mem.c
diff options
context:
space:
mode:
authorchenqijun <chenqijun@corp.netease.com>2021-07-12 10:51:05 +0800
committerDamjan Marion <dmarion@me.com>2021-07-13 16:50:59 +0000
commitf299dc487d36eed0dfbf6d07eb40d8bc58cd724d (patch)
treeeec5e485ee367bfcff56f26ea3d5e445f9c24d06 /src/vppinfra/linux/mem.c
parent041372b79b843b54dfad048dda237e64d1a5f127 (diff)
vppinfra: fix SIGSEGV in clib_mem_vm_unmap
while one mprotect PROT_NONE on hdr->next or hdr->prev, the other one with the PROT_NONE is unmap at the same time, cause SIGSEGV. Type: fix Signed-off-by: arikachen <eaglesora@gmail.com> Change-Id: I21c0497da140c9654b566e47f767a90346715ed8
Diffstat (limited to 'src/vppinfra/linux/mem.c')
-rw-r--r--src/vppinfra/linux/mem.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/src/vppinfra/linux/mem.c b/src/vppinfra/linux/mem.c
index cb46df82552..036890f9c8d 100644
--- a/src/vppinfra/linux/mem.c
+++ b/src/vppinfra/linux/mem.c
@@ -513,14 +513,13 @@ clib_mem_vm_unmap (void *base)
uword size, sys_page_sz = 1ULL << mm->log2_page_sz;
clib_mem_vm_map_hdr_t *hdr = base - sys_page_sz;;
+ map_lock ();
if (mprotect (hdr, sys_page_sz, PROT_READ | PROT_WRITE) != 0)
- return CLIB_MEM_ERROR;
+ goto out;
size = hdr->num_pages << hdr->log2_page_sz;
if (munmap ((void *) hdr->base_addr, size) != 0)
- return CLIB_MEM_ERROR;
-
- map_lock ();
+ goto out;
if (hdr->next)
{
@@ -546,6 +545,9 @@ clib_mem_vm_unmap (void *base)
return CLIB_MEM_ERROR;
return 0;
+out:
+ map_unlock ();
+ return CLIB_MEM_ERROR;
}
__clib_export void