#include #include #include #include #include #include #include #define __KERNEL__ #include extern void sysenter_call(pid_t pid, int signo, short ds, void *addr); extern void sysenter_call_2(pid_t pid, int signo, void *addr); void catch_sig(int signo, struct sigcontext ctx) { __asm__ __volatile__("mov %0, %%ds" : : "r" (__USER_DS)); printf("interrupted %%ebp = 0x%x\n", ctx.ebp); if (ctx.ebp == 0xbaadf00d) printf("phew\n"); } void main(void) { struct user_desc desc; short ds; unsigned long addr; unsigned *stack; unsigned long offset; stack = (unsigned *)mmap(0, 4096, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); stack = &stack[1024]; addr = 0xf0000; offset = __PAGE_OFFSET-(unsigned)stack+addr+16; signal(SIGUSR1, catch_sig); desc.entry_number = 0; desc.base_addr = offset; desc.limit = 0xffffff; desc.seg_32bit = 1; desc.contents = MODIFY_LDT_CONTENTS_DATA; desc.read_exec_only = 0; desc.limit_in_pages = 1; desc.seg_not_present = 0; desc.useable = 1; if (modify_ldt(1, &desc, sizeof(desc)) != 0) { perror("modify_ldt"); } ds = 0x7; /* TI | RPL 3 */ sysenter_call(getpid(), SIGUSR1, ds, stack); sysenter_call_2(getpid(), SIGSTOP, __PAGE_OFFSET+4096); printf("not reached - core should show %%eax == -EFAULT\n"); }