#include #include #include #include #include #include #include #include _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount) static int set_ldt_entry(int entry, unsigned long base, unsigned int limit, int seg_32bit_flag, int contents, int read_only_flag, int limit_in_pages_flag, int seg_not_present, int useable) { struct modify_ldt_ldt_s ldt_info; ldt_info.entry_number = entry; ldt_info.base_addr = base; ldt_info.limit = limit; ldt_info.seg_32bit = seg_32bit_flag; ldt_info.contents = contents; ldt_info.read_exec_only = read_only_flag; ldt_info.limit_in_pages = limit_in_pages_flag; ldt_info.seg_not_present = seg_not_present; ldt_info.useable = useable; return modify_ldt(1, &ldt_info, sizeof(ldt_info)); } void my_trap(int sig) { printf("Test passed, All OK!\n"); exit(0); } int main(int argc, char *argv[]) { unsigned char *ptr; if (mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) == MAP_FAILED) { perror("mmap"); return 1; } if ((ptr = mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) { perror("mmap"); return 1; } if (argc == 1) /* no-Oops mode */ *(unsigned char *)0 = 1; /* Set the no-Oops flag :) */ /* Create the LDT entry */ #define MY_CS (__USER_CS | 4) set_ldt_entry(MY_CS >> 3, (unsigned long)ptr, PAGE_SIZE - 1, 1, MODIFY_LDT_CONTENTS_CODE, 1, 0, 0, 0); ptr[0] = 0xcc; ptr[1] = 0xcb; signal(SIGTRAP, my_trap); asm volatile ("lcall %0,$0\n"::"i"(MY_CS)); printf("Stolen interrupt, very bad.\n"); return 0; }