1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

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.
This commit is contained in:
Zdenek Kabelac 2014-09-19 00:59:46 +02:00
parent 9ffc8615e5
commit 2263a3bcf5

View File

@ -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;
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;
}