Пример #1
0
int main(int argc, char **argv) {
    int retval = 0;
    char *cleanup_dir = envar_path("SINGULARITY_CLEANUPDIR");
    char *trigger = envar_path("SINGULARITY_CLEANUPTRIGGER");
    int trigger_fd;

    singularity_message(DEBUG, "Starting cleanup process\n");

    if ( ( cleanup_dir == NULL ) || ( trigger == NULL ) ) {
        singularity_message(ERROR, "Environment is not properly setup\n");
        ABORT(255);
    }

    if ( is_dir(cleanup_dir) != 0 ) {
        singularity_message(ERROR, "Cleanup location is not a directory: %s\n", cleanup_dir);
        ABORT(255);
    }

    singularity_message(DEBUG, "Opening cleanup trigger file: %s\n", trigger);
    if ( ( trigger_fd = open(trigger, O_RDONLY, 00644) ) < 0 ) {
        singularity_message(ERROR, "Failed opening trigger file %s: %s\n", trigger, strerror(errno));
        ABORT(255);
    }

    singularity_message(DEBUG, "Checking to see if we need to daemonize\n");
    if ( flock(trigger_fd, LOCK_EX | LOCK_NB) != 0 ) {
        singularity_message(VERBOSE, "Daemonizing cleandir cleanup process\n");
        if ( daemon(0, 0) != 0 ) {
            singularity_message(ERROR, "Failed daemonizing cleanup process: %s\n", strerror(errno));
            ABORT(255);
        }
    }

    singularity_message(DEBUG, "Waiting for exclusive flock() on trigger file descriptor: %d\n", trigger_fd);
    if ( flock(trigger_fd, LOCK_EX) == 0 ) {
        singularity_message(VERBOSE, "Cleaning directory: %s\n", cleanup_dir);
        if ( s_rmdir(cleanup_dir) < 0 ) {
            singularity_message(ERROR, "Could not remove directory %s: %s\n", cleanup_dir, strerror(errno));
            ABORT(255);
        }
        close(trigger_fd);
        unlink(trigger);
    }

    return(retval);
}
Пример #2
0
int singularity_action_init(void) {
    char *command = envar("SINGULARITY_COMMAND", "", 10);
    char *libpath = envar_path("SINGULARITY_LD_LIBRARY_PATH");
    singularity_message(DEBUG, "Checking on action to run\n");

    unsetenv("SINGULARITY_COMMAND");
    unsetenv("SINGULARITY_LD_LIBRARY_PATH");

    if ( libpath != NULL ) {
        singularity_message(VERBOSE, "Setting LD_LIBRARY_PATH to `%s`\n", libpath);
        setenv("LD_LIBRARY_PATH", libpath, 1);
        free(libpath);
    }

    if ( command == NULL ) {
        singularity_message(ERROR, "SINGULARITY_COMMAND is undefined\n");
        ABORT(1);
    } else if ( strcmp(command, "shell") == 0 ) {
        singularity_message(DEBUG, "Setting action to: shell\n");
        action = ACTION_SHELL;
        action_shell_init();
    } else if ( strcmp(command, "exec") == 0 ) {
        singularity_message(DEBUG, "Setting action to: exec\n");
        action = ACTION_EXEC;
        action_exec_init();
    } else if ( strcmp(command, "run") == 0 ) {
        singularity_message(DEBUG, "Setting action to: run\n");
        action = ACTION_RUN;
        action_run_init();
    } else if ( strcmp(command, "test") == 0 ) {
        singularity_message(DEBUG, "Setting action to: test\n");
        action = ACTION_TEST;
        action_test_init();
    } else if ( strcmp(command, "start") == 0 ) {
        singularity_message(DEBUG, "Setting action to: start\n");
        action = ACTION_START;
        action_start_init();
    } else if ( strcmp(command, "stop") == 0 ) {
        singularity_message(DEBUG, "Setting action to: stop\n");
        action = ACTION_STOP;
        action_stop_init();
    } else {
        singularity_message(ERROR, "Unknown container action: %s\n", command);
        ABORT(1);
    }

    free(command);

    cwd_path = (char *) malloc(PATH_MAX);

    singularity_message(DEBUG, "Getting current working directory path string\n");
    if ( getcwd(cwd_path, PATH_MAX) == NULL ) {
        singularity_message(ERROR, "Could not obtain current directory path: %s\n", strerror(errno));
        ABORT(1);
    }

    return(0);
}
Пример #3
0
int singularity_image_bind(int argc, char ** argv) {
    uid_t uid = geteuid();
    FILE *containerimage_fp;
    char *containerimage;
    char *loop_dev;

    if ( argv[1] == NULL ) {
        fprintf(stderr, "USAGE: SINGULARITY_IMAGE=[image] %s [command...]\n", argv[0]);
        return(1);
    }

    singularity_message(VERBOSE, "Checking calling user\n");
    if ( uid != 0 ) {
        singularity_message(ERROR, "Calling user must be root\n");
        ABORT(1);
    }

    if ( ( containerimage = envar_path("SINGULARITY_IMAGE") ) == NULL ) {
        singularity_message(ERROR, "SINGULARITY_IMAGE not defined!\n");
        ABORT(255);
    }

    singularity_message(VERBOSE, "Evaluating image: %s\n", containerimage);

    singularity_message(VERBOSE, "Checking if container image exists\n");
    if ( is_file(containerimage) < 0 ) {
        singularity_message(ERROR, "Container image not found: %s\n", containerimage);
        ABORT(1);
    }

    singularity_message(VERBOSE, "Checking if container can be opened read/write\n");
    if ( ( containerimage_fp = fopen(containerimage, "r+") ) == NULL ) { // Flawfinder: ignore
        singularity_message(ERROR, "Could not open image %s: %s\n", containerimage, strerror(errno));
        ABORT(255);
    }

    singularity_priv_init();
    singularity_config_init(joinpath(SYSCONFDIR, "/singularity/singularity.conf"));
    singularity_sessiondir_init(containerimage);
    singularity_ns_mnt_unshare();

    free(containerimage);

    singularity_message(DEBUG, "Binding container to loop interface\n");
    if ( ( loop_dev = singularity_loop_bind(containerimage_fp)) == NULL ) {
        singularity_message(ERROR, "Could not bind image to loop!\n");
        ABORT(255);
    }
    fclose(containerimage_fp);

    singularity_message(VERBOSE, "Setting SINGULARITY_LOOPDEV to '%s'\n", loop_dev);
    setenv("SINGULARITY_LOOPDEV", loop_dev, 1);

    return(0);
}
Пример #4
0
int singularity_action_do(int argc, char **argv) {

    singularity_priv_drop_perm();

    singularity_message(DEBUG, "Trying to change directory to where we started\n");
    char *target_pwd = envar_path("SINGULARITY_TARGET_PWD");
    if (!target_pwd || (chdir(target_pwd) < 0)) {
        if ( chdir(cwd_path) < 0 ) {
            char *homedir;

            singularity_message(DEBUG, "Failed changing directory to: %s\n", cwd_path);
            singularity_message(VERBOSE2, "Changing to home directory\n");

            singularity_message(DEBUG, "Obtaining user's homedir\n");
            homedir = get_homedir(NULL);

            if ( ( homedir != NULL ) && ( chdir(homedir) < 0 ) ) {
                singularity_message(WARNING, "Could not chdir to home directory: %s\n", homedir);
            }
        }
    }
    free(target_pwd);

    if ( action == ACTION_SHELL ) {
        singularity_message(DEBUG, "Running action: shell\n");
        action_shell_do(argc, argv);
    } else if ( action == ACTION_EXEC ) {
        singularity_message(DEBUG, "Running action: exec\n");
        action_exec_do(argc, argv);
    } else if ( action == ACTION_RUN ) {
        singularity_message(DEBUG, "Running action: run\n");
        action_run_do(argc, argv);
    } else if ( action == ACTION_TEST ) {
        singularity_message(DEBUG, "Running action: test\n");
        action_test_do(argc, argv);
    } else if ( action == ACTION_START ) {
        singularity_message(DEBUG, "Running action: start\n");
        action_start_do(argc, argv);
    } else if ( action == ACTION_STOP ) {
        singularity_message(DEBUG, "Running action: stop\n");
        action_stop_do(argc, argv);
    }
    singularity_message(ERROR, "Called singularity_action_do() without singularity_action_init()\n");
    return(-1);
}
Пример #5
0
int main(int argc, char **argv) {
    char *image;

    // Before we do anything, check privileges and drop permission
    singularity_priv_init();
    singularity_priv_drop();

#ifdef SINGULARITY_SUID
    singularity_message(VERBOSE2, "Running SUID program workflow\n");

    singularity_message(VERBOSE2, "Checking program has appropriate permissions\n");
    if ( ( getuid() != 0 ) && ( ( is_owner("/proc/self/exe", 0) < 0 ) || ( is_suid("/proc/self/exe") < 0 ) ) ) {
        singularity_abort(255, "This program must be SUID root\n");
    }

    singularity_message(VERBOSE2, "Checking configuration file is properly owned by root\n");
    if ( is_owner(joinpath(SYSCONFDIR, "/singularity/singularity.conf"), 0 ) < 0 ) {
        singularity_abort(255, "Running in privileged mode, root must own the Singularity configuration file\n");
    }

    singularity_config_init(joinpath(SYSCONFDIR, "/singularity/singularity.conf"));

    singularity_message(VERBOSE2, "Checking that we are allowed to run as SUID\n");
    if ( singularity_config_get_bool(ALLOW_SETUID) == 0 ) {
        singularity_abort(255, "SUID mode has been disabled by the sysadmin... Aborting\n");
    }

    singularity_message(VERBOSE2, "Checking if we were requested to run as NOSUID by user\n");
    if ( envar_defined("SINGULARITY_NOSUID") == TRUE ) {
        singularity_abort(1, "NOSUID mode has been requested... Aborting\n");
    }

#else
    singularity_message(VERBOSE, "Running NON-SUID program workflow\n");

    singularity_message(DEBUG, "Checking program has appropriate permissions\n");
    if ( is_suid("/proc/self/exe") >= 0 ) {
        singularity_abort(255, "This program must **NOT** be SUID\n");
    }

    singularity_config_init(joinpath(SYSCONFDIR, "/singularity/singularity.conf"));

    if ( singularity_priv_getuid() != 0 ) {
        singularity_message(VERBOSE2, "Checking that we are allowed to run as SUID\n");
        if ( singularity_config_get_bool(ALLOW_SETUID) == 1 ) {
            singularity_message(VERBOSE2, "Checking if we were requested to run as NOSUID by user\n");
            if ( envar_defined("SINGULARITY_NOSUID") == FALSE ) {
                char sexec_suid_path[] = LIBEXECDIR "/singularity/sexec-suid";
		
		singularity_message(VERBOSE, "Checking for sexec-suid at %s\n", sexec_suid_path);

		if ( is_file(sexec_suid_path) == 0 ) {
                    if ( ( is_owner(sexec_suid_path, 0 ) == 0 ) && ( is_suid(sexec_suid_path) == 0 ) ) {
                        singularity_message(VERBOSE, "Invoking SUID sexec: %s\n", sexec_suid_path);

                        execv(sexec_suid_path, argv); // Flawfinder: ignore
                        singularity_abort(255, "Failed to execute sexec binary (%s): %s\n", sexec_suid_path, strerror(errno));
                    } else {
                        singularity_message(VERBOSE, "Not invoking SUID mode: SUID sexec permissions not properly set\n");
                    }
		}
		else {
		    singularity_message(VERBOSE, "Not invoking SUID mode: SUID sexec not installed\n");
		}
            } else {
                singularity_message(VERBOSE, "Not invoking SUID mode: NOSUID mode requested\n");
            }
        } else {
            singularity_message(VERBOSE, "Not invoking SUID mode: disallowed by the system administrator\n");
        }
    } else {
        singularity_message(VERBOSE, "Not invoking SUID mode: running as root\n");
    }

#endif /* SINGULARITY_SUID */

    if ( ( image = envar_path("SINGULARITY_IMAGE") ) == NULL ) {
        singularity_abort(255, "SINGULARITY_IMAGE not defined!\n");
    }

    singularity_action_init();
    singularity_rootfs_init(image);
    singularity_sessiondir_init(image);

    free(image);

    singularity_ns_unshare();

    singularity_rootfs_mount();

    singularity_rootfs_check();

    singularity_file();

    singularity_mount();

    singularity_rootfs_chroot();

    singularity_action_do(argc, argv);

    return(0);

}
Пример #6
0
void singularity_mount_scratch(void) {
    char *container_dir = singularity_rootfs_dir();
    char *scratchdir_path;
    char *tmpdir_path;
    char *sourcedir_path;
    int r;

    singularity_message(DEBUG, "Getting SINGULARITY_SCRATCHDIR from environment\n");
    if ( ( scratchdir_path = envar_path("SINGULARITY_SCRATCHDIR") ) == NULL ) {
        singularity_message(DEBUG, "Not mounting scratch directory: Not requested\n");
        return;
    }

    singularity_message(DEBUG, "Checking configuration file for 'user bind control'\n");
    if ( singularity_config_get_bool(USER_BIND_CONTROL) <= 0 ) {
        singularity_message(VERBOSE, "Not mounting scratch: user bind control is disabled by system administrator\n");
        return;
    }

#ifndef SINGULARITY_NO_NEW_PRIVS
        singularity_message(WARNING, "Not mounting scratch: host does not support PR_SET_NO_NEW_PRIVS\n");
        return;
#endif  

    singularity_message(DEBUG, "Checking if overlay is enabled\n");
    int overlayfs_enabled = singularity_rootfs_overlay_enabled() > 0;
    if ( !overlayfs_enabled ) {
        singularity_message(VERBOSE, "Overlay is not enabled: cannot make directories not preexisting in container scratch.\n");
    }

    singularity_message(DEBUG, "Checking SINGULARITY_WORKDIR from environment\n");
    if ( ( tmpdir_path = envar_path("SINGULARITY_WORKDIR") ) == NULL ) {
        if ( ( tmpdir_path = singularity_sessiondir_get() ) == NULL ) {
            singularity_message(ERROR, "Could not identify a suitable temporary directory for scratch\n");
            return;
        }
    }

    sourcedir_path = joinpath(tmpdir_path, "/scratch");

    free(tmpdir_path);

    char *outside_token = NULL;
    char *current = strtok_r(strdup(scratchdir_path), ",", &outside_token);

    free(scratchdir_path);

    while ( current != NULL ) {

        char *full_sourcedir_path = joinpath(sourcedir_path, basename(strdup(current)));

        if ( s_mkpath(full_sourcedir_path, 0750) < 0 ) {
             singularity_message(ERROR, "Could not create scratch working directory %s: %s\n", full_sourcedir_path, strerror(errno));
             ABORT(255);
         }

        if (overlayfs_enabled) {
            singularity_priv_escalate();
            singularity_message(DEBUG, "Creating scratch directory inside container\n");
            r = s_mkpath(joinpath(container_dir, current), 0755);
            singularity_priv_drop();
            if ( r < 0 ) {
                singularity_message(VERBOSE, "Skipping scratch directory mount, could not create dir inside container %s: %s\n", current, strerror(errno));
                return;
            }
        }

        singularity_priv_escalate();
        singularity_message(VERBOSE, "Binding '%s' to '%s/%s'\n", full_sourcedir_path, container_dir, current);
        r = mount(full_sourcedir_path, joinpath(container_dir, current), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL);
        if ( singularity_priv_userns_enabled() != 1 ) {
            r += mount(NULL, joinpath(container_dir, current), NULL, MS_BIND|MS_NOSUID|MS_REC|MS_REMOUNT, NULL);
        }
        singularity_priv_drop();
        if ( r < 0 ) {
            singularity_message(WARNING, "Could not bind scratch directory into container %s: %s\n", full_sourcedir_path, strerror(errno));
            ABORT(255);
        }

        current = strtok_r(NULL, ",", &outside_token);
        // Ignore empty directories.
        while (current && !strlength(current, 1024)) {current = strtok_r(NULL, ",", &outside_token);}
    }
    return;
}
Пример #7
0
int singularity_mount_tmp(void) {
    char *container_dir = singularity_rootfs_dir();
    char *tmp_source;
    char *vartmp_source;

    singularity_config_rewind();
    if ( singularity_config_get_bool("mount tmp", 1) <= 0 ) {
        singularity_message(VERBOSE, "Skipping tmp dir mounting (per config)\n");
        return(0);
    }

    if ( envar_defined("SINGULARITY_CONTAIN") == TRUE ) {
        char *tmpdirpath;
        if ( ( tmpdirpath = envar_path("SINGULARITY_WORKDIR") ) != NULL ) {
            singularity_config_rewind();
            if ( singularity_config_get_bool("user bind control", 1) <= 0 ) {
                singularity_message(ERROR, "User bind control is disabled by system administrator\n");
                ABORT(5);
            }
            tmp_source = joinpath(tmpdirpath, "/tmp");
            vartmp_source = joinpath(tmpdirpath, "/var_tmp");
        } else {
            char *sessiondir = singularity_sessiondir_get();
            tmp_source = joinpath(sessiondir, "/tmp");
            vartmp_source = joinpath(sessiondir, "/var_tmp");
        }
        free(tmpdirpath);
    } else {
        tmp_source = strdup("/tmp");
        vartmp_source = strdup("/var/tmp");
    }

    if ( s_mkpath(tmp_source, 0755) < 0 ) {
        singularity_message(ERROR, "Could not create source /tmp directory %s: %s\n", tmp_source, strerror(errno));
        ABORT(255);
    }
    if ( is_dir(tmp_source) == 0 ) {
        if ( is_dir(joinpath(container_dir, "/tmp")) == 0 ) {
            singularity_priv_escalate();
            singularity_message(VERBOSE, "Mounting directory: /tmp\n");
            if ( mount(tmp_source, joinpath(container_dir, "/tmp"), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) {
                singularity_message(ERROR, "Failed to mount %s -> /tmp: %s\n", tmp_source, strerror(errno));
                ABORT(255);
            }
            singularity_priv_drop();
        } else {
            singularity_message(VERBOSE, "Could not mount container's /tmp directory: does not exist\n");
        }
    } else {
        singularity_message(VERBOSE, "Could not mount host's /tmp directory (%s): does not exist\n", tmp_source);
    }

    if ( s_mkpath(vartmp_source, 0755) < 0 ) {
        singularity_message(ERROR, "Could not create source /var/tmp directory %s: %s\n", vartmp_source, strerror(errno));
        ABORT(255);
    }
    if ( is_dir(vartmp_source) == 0 ) {
        if ( is_dir(joinpath(container_dir, "/var/tmp")) == 0 ) {
            singularity_priv_escalate();
            singularity_message(VERBOSE, "Mounting directory: /var/tmp\n");
            if ( mount(vartmp_source, joinpath(container_dir, "/var/tmp"), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) {
                singularity_message(ERROR, "Failed to mount %s -> /var/tmp: %s\n", vartmp_source, strerror(errno));
                ABORT(255);
            }
            singularity_priv_drop();
        } else {
            singularity_message(VERBOSE, "Could not mount container's /var/tmp directory: does not exist\n");
        }
    } else {
        singularity_message(VERBOSE, "Could not mount host's /var/tmp directory (%s): does not exist\n", vartmp_source);
    }

    free(tmp_source);
    free(vartmp_source);

    return(0);
}