From: Masatake YAMATO Date: Fri, 16 Feb 2018 19:37:11 +0000 (+0900) Subject: mmap_cache: record protection bits X-Git-Tag: v4.22~162 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=71d33e5e3ec75f484e786824729aed003321e950;p=strace mmap_cache: record protection bits To make mmap_cache reusable, records protection bits of mmap entries. * defs.h (mmap_cache_protection): New enum. * mmap_cache.c (build_mmpa_cache): Don't ignore entries that are not executable, just record the protection bits here. * unwind.c (print_stack_frame): Ignore entries that are not executable. Signed-off-by: Masatake YAMATO --- diff --git a/defs.h b/defs.h index 97bdcd80..9f184c08 100644 --- a/defs.h +++ b/defs.h @@ -733,14 +733,23 @@ struct mmap_cache_t { * start_addr is 0x7fabbb09b000 * end_addr is 0x7fabbb09f000 * mmap_offset is 0x179000 + * protections is MMAP_CACHE_PROT_READABLE|MMAP_CACHE_PROT_EXECUTABLE * binary_filename is "/lib/libc-2.11.1.so" */ unsigned long start_addr; unsigned long end_addr; unsigned long mmap_offset; + unsigned char protections; char *binary_filename; }; +enum mmap_cache_protection { + MMAP_CACHE_PROT_READABLE = 1 << 0, + MMAP_CACHE_PROT_WRITABLE = 1 << 1, + MMAP_CACHE_PROT_EXECUTABLE = 1 << 2, + MMAP_CACHE_PROT_SHARED = 1 << 3, +}; + enum mmap_cache_rebuild_result { MMAP_CACHE_REBUILD_NOCACHE, MMAP_CACHE_REBUILD_READY, diff --git a/mmap_cache.c b/mmap_cache.c index 0c6e2b7e..f26d2a78 100644 --- a/mmap_cache.c +++ b/mmap_cache.c @@ -68,16 +68,26 @@ build_mmap_cache(struct tcb *tcp) while (fgets(buffer, sizeof(buffer), fp) != NULL) { struct mmap_cache_t *entry; unsigned long start_addr, end_addr, mmap_offset; + char read_bit; + char write_bit; char exec_bit; + char shared_bit; char binary_path[sizeof(buffer)]; - if (sscanf(buffer, "%lx-%lx %*c%*c%c%*c %lx %*x:%*x %*d %[^\n]", - &start_addr, &end_addr, &exec_bit, - &mmap_offset, binary_path) != 5) + if (sscanf(buffer, "%lx-%lx %c%c%c%c %lx %*x:%*x %*d %[^\n]", + &start_addr, &end_addr, + &read_bit, &write_bit, &exec_bit, &shared_bit, + &mmap_offset, binary_path) != 8) continue; - /* ignore mappings that have no PROT_EXEC bit set */ - if (exec_bit != 'x') + /* skip mappings that have unknown protection */ + if (!(read_bit == '-' || read_bit == 'r')) + continue; + if (!(write_bit == '-' || write_bit == 'w')) + continue; + if (!(exec_bit == '-' || exec_bit == 'x')) + continue; + if (!(shared_bit == 'p' || shared_bit == 's')) continue; if (end_addr < start_addr) { @@ -116,6 +126,13 @@ build_mmap_cache(struct tcb *tcp) entry->start_addr = start_addr; entry->end_addr = end_addr; entry->mmap_offset = mmap_offset; + entry->protections = ( + 0 + | ((read_bit == 'r')? MMAP_CACHE_PROT_READABLE : 0) + | ((write_bit == 'w')? MMAP_CACHE_PROT_WRITABLE : 0) + | ((exec_bit == 'x')? MMAP_CACHE_PROT_EXECUTABLE: 0) + | ((shared_bit == 's')? MMAP_CACHE_PROT_SHARED : 0) + ); entry->binary_filename = xstrdup(binary_path); tcp->mmap_cache_size++; } diff --git a/unwind.c b/unwind.c index 56a7b9ce..ef98fc99 100644 --- a/unwind.c +++ b/unwind.c @@ -139,7 +139,9 @@ print_stack_frame(struct tcb *tcp, } cur_mmap_cache = mmap_cache_search(tcp, ip); - if (cur_mmap_cache) { + if (cur_mmap_cache + /* ignore mappings that have no PROT_EXEC bit set */ + && (cur_mmap_cache->protections & MMAP_CACHE_PROT_EXECUTABLE)) { unsigned long true_offset; unw_word_t function_offset;