int _load_python(const char *dllname, const char *bytes, size_t size) { int i; struct IMPORT *p = imports; void * hmod; bool resolved = true; dprint("Trying to find python symbols in current process\n"); for (i = 0; p->name && resolved; ++i, ++p) { p->proc = (void (*)()) dlsym(NULL, p->name); if (p->proc == NULL) { dprint("undefined symbol %s -> exit(-1). Fallback to built-in python\n", p->name); resolved = false; } } if (resolved) { return 1; } dprint("Trying to load embedded python library\n"); hmod = memdlopen(dllname, bytes, size); if (hmod == NULL) { dprint("Couldn't load embedded python library: %s\n", dlerror()); return 0; } p = imports; for (i = 0; p->name; ++i, ++p) { p->proc = (void (*)()) dlsym(hmod, p->name); dprint("Python: %s -> %p\n", p->name, p->proc); if (p->proc == NULL) { dprint("undefined symbol %s -> exit(-1)\n", p->name); return 0; } } return 1; }
static void install_syscall_filter(void) { struct sock_filter filter[] = { /* Validate architecture. */ VALIDATE_ARCHITECTURE, /* Grab the system call number. */ EXAMINE_SYSCALL, /* List allowed syscalls. */ ALLOW_SYSCALL(rt_sigreturn), ALLOW_SYSCALL(exit), ALLOW_SYSCALL(exit_group), ALLOW_SYSCALL(read), ALLOW_SYSCALL(write), ALLOW_SYSCALL(mmap), ALLOW_SYSCALL(munmap), ALLOW_SYSCALL(mprotect), ALLOW_SYSCALL(getcwd), KILL_PROCESS, }; struct sock_fprog prog = { .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])), .filter = filter, }; if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) err(1, "prctl(NO_NEW_PRIVS)"); if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) err(1, "prctl(SECCOMP)"); } static void receive_and_exec_code(int s) { unsigned int size; void (*f)(void); int prot; char op; void *p; readall(s, &op, sizeof(op)); readall(s, &size, sizeof(size)); if (size > MAX_SIZE) errx(1, "size too large: %d", size); prot = PROT_READ | PROT_WRITE | PROT_EXEC; p = mmap(NULL, size, prot, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if (p == MAP_FAILED) err(1, "mmap"); readall(s, p, size); switch (op) { case '0': f = p; f(); break; case '1': memdlopen(size, p); break; default: break; } _exit(0); }