[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] Trying to reproduce %eip corruption
Hi, I was trying to reproduce the error of %eip corruption and I manage to get a small test program (from my previous one). ---------- /* * This program try to cause an exception raising a Xen failsafe callback * The idea is: * - one thread execute an infinite loop with some int3 instructions before * and a CS segment allocated in LDT while handling a timer signal * - another thread just make sure that first is in the infinite loop and * set CS to cause an exception on the first one * The first thread does not core just after the LDT change cause CS is cached * to it crash when kernel try to return to it. * Actually the first one running in the infinite loop can be stopped only by * an hardware interrupt so you have a Xen callback which try to return and * get an exception while doing IRET */ #undef NDEBUG #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <signal.h> #include <assert.h> #include <sys/time.h> #include <sys/syscall.h> #include <sys/mman.h> #include <asm/ldt.h> #include <pthread.h> #define LDT_READ 0 #define LDT_WRITE 1 static void handler(int sig) { static unsigned count = 0; if (++count == 60 * 1000) exit(0); } static void segv_handler(int sig) { exit(0); } static int cs_ldt = -1; static void change_cs(void) { struct user_desc desc; /* fills desc which represents the code segment */ desc.entry_number = 0; desc.base_addr = 0; desc.limit = 0xffffffffu >> 12; desc.seg_32bit = 0x1; desc.contents = 0x2; desc.read_exec_only = 0x1; desc.limit_in_pages = 0x1; desc.seg_not_present = 0x0; desc.useable = 0x1; /* Writes a user_desc struct to the ldt */ int err = syscall(SYS_modify_ldt, LDT_WRITE, &desc, sizeof(desc)); assert(!err); /* set cs to our selector to be able to make it core */ asm( " pushl %eax\n" " movl $0x7, %eax\n" /* 0111: 0-Index 1-Using the LDT table 11-RPL of 3 */ " pushl %eax\n" " pushl $1f\n" " retf\n" "1:\n" " popl %eax\n" ); cs_ldt = (desc.entry_number << 3) | 7; } static void * corrupt_cs(void *arg) { /* this assure that we set the selector while in the loop */ sleep(2); assert(cs_ldt >= 0); struct user_desc desc; /* fills desc which represents the code segment */ desc.entry_number = cs_ldt >> 3; desc.base_addr = 0; desc.limit = 1; desc.seg_32bit = 0x1; desc.contents = 0x2; desc.read_exec_only = 0x1; desc.limit_in_pages = 0x1; desc.seg_not_present = 0x1; desc.useable = 0x1; /* Writes a user_desc struct to the ldt */ int err = syscall(SYS_modify_ldt, LDT_WRITE, &desc, sizeof(desc)); assert(!err); return NULL; } static void faulty(void) { #if !defined(__x86_64__) && !defined(__i386__) # error This code work only on Intel architecture! #endif // wait for a core !! asm( #ifdef __x86_64__ " mov $-513, %rax\n" #else " mov $-513, %eax\n" #endif " jmp 1f\n" " int $3\n" " int $3\n" " int $3\n" " int $3\n" "1:\n" " jmp 1b\n" ); } int main(void) { struct sigaction act; // set signal sigfillset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = handler; int err = sigaction(SIGALRM, &act, NULL); assert(!err); act.sa_handler = segv_handler; err = sigaction(SIGSEGV, &act, NULL); assert(!err); // set timer struct itimerval ival = { { 0, 1000 }, { 0, 1000 } }; err = setitimer(ITIMER_REAL, &ival, NULL); assert(!err); pthread_t thread_id; err = pthread_create(&thread_id, NULL, corrupt_cs, NULL); assert(!err); /* for some reasons pthread_create restre original cs */ change_cs(); /* faulting with SEGV is ok! */ faulty(); return 0; } ---------- I run the program with this shell script ---------- #!/bin/bash set -e cd / test -x xencore32 while true; do echo running test set +e su nobody -s /xencore32 && echo ok set -e done ---------- The problems are now two: - when program crash "normally" is cause an invalid instruction to be executed while it should raise a SEGV - sometimes it crashes very badly with an exception on the kernel and after a couple of time you can be lucky and have your dom0 quite useless. When it crashes very badly I got this on screen (I couldn't use dmesg) [ 242.372564] Process xencore32 (pid: 6645, ti=e797e000 task=e98957f0 task.ti=e797e000) [ 242.372615] Stack: [ 242.372665] Call Trace: [ 242.372691] <IRQ> [ 242.373864] Process xencore32 (pid: 6645, ti=e797e000 task=e98957f0 task.ti=e797e000) [ 242.373916] Stack: [ 242.374243] Call Trace: [ 242.374803] Code: 8b 4d 10 85 c9 74 13 3b 5d 10 73 32 8b 45 10 2d 00 20 00 00 39 c3 73 13 eb 24 3b 5d f0 76 1f 8b 45 f0 05 fc 1f 00 00 39 c3 [ 242.375302] EIP: [<c1013c04>] print_context_stack+0x94/0xc0 SS:ESP 0069:e797fe00 Anybody has some hint on how to resolve this problem? Regards Frediano _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |