Ejemplo n.º 1
0
/// Destructor that removes signal masking.
signals::interrupts_inhibiter::~interrupts_inhibiter(void)
{
    unmask_signals();
    interrupts_inhibiter_active = false;
}
Ejemplo n.º 2
0
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;
}