/// Destructor that removes signal masking. signals::interrupts_inhibiter::~interrupts_inhibiter(void) { unmask_signals(); interrupts_inhibiter_active = false; }
int main(int argc, char* const argv[]) { char* jail_base; char* jail_src_base; char* jail_system; char* jailpath; char* work_dir; char* prog; char* const * args; int uid; gid_t groups[1]; int arg_num = 1; int daemon_mode = 0; int unlimited = 0; char canonical_jailpath[PATH_MAX]; /* Disallow execution from all users but the whitelisted ones, and root */ if (!uid_allowed(getuid())) { fprintf(stderr, "only the web server may execute trampoline\n"); exit(1); } /* Args check and usage */ if (argc < 5) { usage(argv[0]); } if (strcmp(argv[arg_num], "-d") == 0) { if (argc < 6) { usage(argv[0]); } daemon_mode = 1; arg_num++; } if (strcmp(argv[arg_num], "-u") == 0) { if (argc < 6) { usage(argv[0]); } unlimited = 1; arg_num++; } uid = atoi(argv[arg_num++]); jail_base = argv[arg_num++]; jail_src_base = argv[arg_num++]; jail_system = argv[arg_num++]; jailpath = argv[arg_num++]; work_dir = argv[arg_num++]; prog = argv[arg_num]; args = argv + arg_num; /* Disallow suiding to the root user */ if (uid == 0) { fprintf(stderr, "cannot set up a jail as root\n"); exit(1); } /* Jail path must be an absolute path, * and it must begin with jail_base. */ if (norm(canonical_jailpath, PATH_MAX, jailpath) != 0) { fprintf(stderr, "bad jail path: %s\n", jailpath); exit(1); } if (strncmp(canonical_jailpath, jail_base, strlen(jail_base))) { fprintf(stderr, "bad jail path: %s\n", jailpath); exit(1); } openlog("trampoline", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER); #ifdef IVLE_AUFS_JAILS mount_if_needed(jail_src_base, jail_base, jail_system, canonical_jailpath); #endif /* IVLE_AUFS_JAILS */ /* chroot into the jail. * Henceforth this process, and its children, cannot see anything above * canoncial_jailpath. */ if (chroot(canonical_jailpath)) { syslog(LOG_ERR, "chroot to %s failed\n", canonical_jailpath); perror("could not chroot"); exit(1); } /* chdir into the specified working directory */ if (chdir(work_dir)) { perror("could not chdir"); exit(1); } /* setuid to the given user ID. * Henceforth we will be running as this user instead of root. */ if (setgid(uid)) { perror("could not setgid"); exit(1); } groups[0] = uid; if (setgroups(1, groups)) { perror("could not setgroups"); exit(1); } if (setuid(uid)) { perror("could not setuid"); exit(1); } /* set user resource limits */ if (!unlimited) { struct rlimit l; /* Process adress space in memory */ l.rlim_cur = 448 * 1024 * 1024; /* 512MiB - 64MiB */ l.rlim_max = 512 * 1024 * 1024; /* 512MiB */ if (setrlimit(RLIMIT_AS, &l)) { perror("could not setrlimit/RLIMIT_AS"); exit(1); } /* Process data segment in memory * Note: This requires a kernel patch to work correctly otherwise it is * ineffective (thus you are only limited by RLIMIT_AS) */ l.rlim_cur = 448 * 1024 * 1024; /* 512MiB - 64MiB */ l.rlim_max = 512 * 1024 * 1024; /* 512MiB */ if (setrlimit(RLIMIT_DATA, &l)) { perror("could not setrlimit/RLIMIT_DATA"); exit(1); } /* Core */ l.rlim_cur = 0; /* No core files */ l.rlim_max = 0; /* No core files */ if (setrlimit(RLIMIT_CORE, &l)) { perror("could not setrlimit/RLIMIT_CORE"); exit(1); } /* CPU */ l.rlim_cur = 25; /* 25 Seconds */ l.rlim_max = 30; /* 30 Seconds */ if (setrlimit(RLIMIT_CPU, &l)) { perror("could not setrlimit/RLIMIT_CPU"); exit(1); } /* File Size */ l.rlim_cur = 64 * 1024 * 1024; /* 64MiB */ l.rlim_max = 72 * 1024 * 1024; /* 72MiB */ if (setrlimit(RLIMIT_FSIZE, &l)) { perror("could not setrlimit/RLIMIT_FSIZE"); exit(1); } /* Number of Processes */ l.rlim_cur = 50; l.rlim_max = 50; if (setrlimit(RLIMIT_NPROC, &l)) { perror("could not setrlimit/RLIMIT_NPROC"); exit(1); } } /* Remove any signal handler masks so we can send signals to the child */ if(unmask_signals()) { perror("could not unmask signals"); exit(1); } /* If everything was OK daemonize (if required) */ if (daemon_mode) { daemonize(); } /* exec (replace this process with the a new instance of the target * program). Pass along all the arguments. * Note that for script execution, the "program" will be the interpreter, * and the first argument will be the script. */ execv(prog, args); /* nb exec won't return unless there was an error */ syslog(LOG_ERR, "exec of %s in %s failed", prog, canonical_jailpath); perror("could not exec"); closelog(); return 1; }