static long dune_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { long r = -EINVAL; struct dune_config conf; struct dune_layout layout; switch (ioctl) { case DUNE_ENTER: r = copy_from_user(&conf, (int __user *) arg, sizeof(struct dune_config)); if (r) { r = -EIO; goto out; } r = dune_enter(&conf, &conf.ret); if (r) break; r = copy_to_user((void __user *)arg, &conf, sizeof(struct dune_config)); if (r) { r = -EIO; goto out; } break; case DUNE_GET_SYSCALL: rdmsrl(MSR_LSTAR, r); printk(KERN_INFO "R %lx\n", (unsigned long) r); break; case DUNE_GET_LAYOUT: layout.phys_limit = (1UL << boot_cpu_data.x86_phys_bits); layout.base_map = LG_ALIGN(current->mm->mmap_base) - GPA_MAP_SIZE; layout.base_stack = LG_ALIGN(current->mm->start_stack) - GPA_STACK_SIZE; r = copy_to_user((void __user *)arg, &layout, sizeof(struct dune_layout)); if (r) { r = -EIO; goto out; } break; case DUNE_TRAP_ENABLE: r = dune_trap_enable(arg); break; case DUNE_TRAP_DISABLE: r = dune_trap_disable(arg); break; default: return -ENOTTY; } out: return r; }
static int test_pthread(void) { pthread_t pt; void *ret; if (dune_enter()) return 1; if (check_dune()) return 2; if (pthread_create(&pt, NULL, test_pthread_thread, NULL)) err(1, "pthread_create()"); if (check_dune()) return 3; if (pthread_join(pt, &ret)) return 4; if (ret != (void*) 0x666) return 5; if (check_dune()) return 6; return 255; }
int main() { int ret,i; ret = dune_init(0); if (ret) { printf("server:failed to initialize Dune\n"); return ret; } ret = dune_enter(); if (ret) { printf("server: failed to enter Dune mode\n"); return ret; } for (i = 0; i < 23; i++) { pid_t pid; if ((pid = fork()) == 0) { for (;;) { int s = 1; s += s; } } } for (;;) { int s = 1; s += s; } }
static long dune_clone(struct dune_tf *tf) { unsigned long fs; int rc; unsigned long pc; rdmsrl(MSR_GS_BASE, pc); if (ARG1(tf) != 0) return dune_pthread_create(tf); fs = dune_get_user_fs(); rc = syscall(SYS_clone, ARG0(tf), ARG1(tf), ARG2(tf), ARG3(tf), ARG4(tf)); if (rc < 0) return -errno; if (rc == 0) { dune_enter(); dune_set_user_fs(fs); } return rc; }
int boxer_main(int argc, char *argv[]) { int ret; uintptr_t sp; struct elf_data data; if (argc < 2) return -EINVAL; /* XXX needed. Probably does some libc stuff */ printf(" \b"); // printf("%s\n", environ[0]); ret = dune_init(0); if (ret) { printf("sandbox: failed to initialize Dune\n"); return ret; } ret = dune_enter(); if (ret) { printf("sandbox: failed to enter Dune mode\n"); return ret; } ret = load_elf(argv[1], &data); if (ret) return ret; // printf("sandbox: entry addr is %lx\n", data.entry); dune_set_user_fs(0); // default starting fs ret = trap_init(); if (ret) { printf("failed to initialize trap handlers\n"); return ret; } ret = umm_alloc_stack(&sp); if (ret) { printf("failed to alloc stack\n"); return ret; } sp = setup_arguments(sp, argv[1], &argv[2], environ, data); if (!sp) { printf("failed to setup arguments\n"); return -EINVAL; } ret = run_app(sp, data.entry); return ret; }
static void *test_pthread_thread(void *arg) { if (dune_enter()) return NULL; if (check_dune()) return NULL; return (void*) 0x666; }
static int test_fork(void) { int pid; int rc; if (dune_enter()) return 1; if (check_dune()) return 2; pid = fork(); if (pid == -1) return 3; /* child */ if (pid == 0) { if (dune_enter()) return 1; if (check_dune()) exit(1); exit(69); } else { if (check_dune()) return 4; if (waitpid(pid, &rc, 0) == -1) err(5, "waitpid()"); if (WEXITSTATUS(rc) != 69) return 6; } return 255; }
void *pthread_entry(void *arg) { struct thread_arg *a = arg; struct dune_tf *tf = a->ta_tf; struct dune_tf child_tf; int *tidp = NULL; pid_t tid; int flags = ARG0(tf); if (!a->dune_started) dune_enter(); tid = syscall(SYS_gettid); /* XXX validate */ /* set up tls */ if (flags & CLONE_SETTLS) dune_set_user_fs(ARG4(tf)); if (flags & CLONE_PARENT_SETTID) { tidp = (int *) ARG2(tf); *tidp = tid; } if (flags & CLONE_CHILD_CLEARTID) { tidp = (int *) ARG3(tf); syscall(SYS_set_tid_address, tidp); } /* enter thread */ memcpy(&child_tf, tf, sizeof(child_tf)); child_tf.rip = tf->rip; child_tf.rax = 0; child_tf.rsp = ARG1(tf); /* tell parent tid */ pthread_mutex_lock(&a->ta_mtx); a->ta_tid = tid; pthread_mutex_unlock(&a->ta_mtx); pthread_cond_signal(&a->ta_cnd); do_enter_thread(&child_tf); return NULL; }
static int test_signal(void) { int pid; if (dune_enter()) return 1; pid = getpid(); if (dune_signal(SIGUSR1, test_signal_handler) == SIG_ERR) err(1, "signal()"); if (kill(pid, SIGUSR1) == -1) err(1, "kill()"); if (test_signal_glob != 666) return 2; return 255; }