diff options
author | Zdenek Kabelac <zkabelac@redhat.com> | 2014-09-19 00:59:46 +0200 |
---|---|---|
committer | Zdenek Kabelac <zkabelac@redhat.com> | 2014-09-19 01:10:58 +0200 |
commit | 2263a3bcf559ef1eba68a6ef6216aca4deaf4d3e (patch) | |
tree | c522d44e15bfdd7c42e2160fce7c5d71dadb0040 | |
parent | 9ffc8615e54c804180137b02106c5bff2671061c (diff) | |
download | lvm2-2263a3bcf559ef1eba68a6ef6216aca4deaf4d3e.tar.gz |
debug: mmap traps mmap and mmap64 on i386
Add code to trap both mmap implementation on 32bit arch.
Use dlsym()
Use hlt instraction instead of int3 - generates usable stack trace
when problem is catched.
-rw-r--r-- | lib/mm/memlock.c | 62 |
1 files changed, 46 insertions, 16 deletions
diff --git a/lib/mm/memlock.c b/lib/mm/memlock.c index 25d55f319..a58efd9e4 100644 --- a/lib/mm/memlock.c +++ b/lib/mm/memlock.c @@ -333,30 +333,35 @@ static int _memlock_maps(struct cmd_context *cmd, lvmlock_t lock, size_t *mstats #endif /* DEBUG_MEMLOCK */ #ifdef ARCH_X86 +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include <dlfcn.h> static char _mmap_orig; static unsigned char *_mmap_addr; -#endif +#ifdef __i386__ +static char _mmap64_orig; +static unsigned char *_mmap64_addr; +#endif /* __i386__ */ +#endif /* ARCH_X86 */ static int _disable_mmap(void) { #ifdef ARCH_X86 - volatile unsigned char *plt, *abs_addr; + volatile unsigned char *abs_addr; if (!_mmap_addr) { - (void) mmap(NULL, -1, -1, -1, -1, -1); - plt = (unsigned char *)mmap; - if (plt[0] != 0xff || plt[1] != 0x25) { - log_debug("Can't find PLT jump entry assuming -fPIE linkage."); - _mmap_addr = plt; - } else { + _mmap_addr = (unsigned char *) dlsym(RTLD_NEXT, "mmap"); + if (_mmap_addr[0] == 0xff && _mmap_addr[1] == 0x25) { /* plt */ #ifdef __x86_64__ - abs_addr = plt + 6 + *(int32_t *)(plt + 2); + abs_addr = _mmap_addr + 6 + *(int32_t *)(_mmap_addr + 2); #endif /* __x86_64__ */ #ifdef __i386__ - abs_addr = *(void **)(plt + 2); + abs_addr = *(void **)(_mmap_addr + 2); #endif /* __i386__ */ _mmap_addr = *(void **)abs_addr; - } + } else + log_debug("Can't find PLT jump entry assuming -fPIE linkage."); if (mprotect((void *)((unsigned long)_mmap_addr & ~4095UL), 4096, PROT_READ|PROT_WRITE|PROT_EXEC)) { log_sys_error("mprotect", ""); _mmap_addr = NULL; @@ -364,8 +369,27 @@ static int _disable_mmap(void) } _mmap_orig = *_mmap_addr; } - *_mmap_addr = 0xcc; + *_mmap_addr = 0xf4; log_debug("Remapped mmap jump entry %x to %x.", _mmap_orig, *_mmap_addr); + +#ifdef __i386__ + if (!_mmap64_addr) { + _mmap64_addr = (unsigned char *) dlsym(RTLD_NEXT, "mmap64"); + if (_mmap64_addr[0] == 0xff && _mmap64_addr[1] == 0x25) { + abs_addr = *(void **)(_mmap64_addr + 2); + _mmap64_addr = *(void **)abs_addr; + } else + log_debug("Can't find PLT jump entry assuming -fPIE linkage."); + if (mprotect((void *)((unsigned long)_mmap64_addr & ~4095UL), 4096, PROT_READ|PROT_WRITE|PROT_EXEC)) { + log_sys_error("mprotect", ""); + _mmap64_addr = NULL; + return 0; + } + _mmap64_orig = *_mmap64_addr; + } + *_mmap64_addr = 0xf4; + log_debug("Remapped mmap64 jump entry %x to %x.", _mmap64_orig, *_mmap64_addr); +#endif /* __i386__ */ #endif /* ARCH_X86 */ return 1; } @@ -373,10 +397,16 @@ static int _disable_mmap(void) static int _restore_mmap(void) { #ifdef ARCH_X86 - if (!_mmap_addr) - return 0; - log_debug("Restoring mmap jump entry."); - *_mmap_addr = _mmap_orig; + if (_mmap_addr) { + log_debug("Restoring mmap jump entry."); + *_mmap_addr = _mmap_orig; + } +#ifdef __i386__ + if (_mmap64_addr) { + log_debug("Restoring mmap64 jump entry."); + *_mmap64_addr = _mmap64_orig; + } +#endif /* __i386__ */ #endif /* ARCH_X86 */ return 1; } |