int singularity_ns_ipc_unshare(void) { singularity_config_rewind(); if ( singularity_config_get_bool("allow ipc ns", 1) <= 0 ) { singularity_message(VERBOSE2, "Not virtualizing IPC namespace by configuration\n"); return(0); } if ( envar_defined("SINGULARITY_UNSHARE_IPC") == FALSE ) { singularity_message(VERBOSE2, "Not virtualizing IPC namespace on user request\n"); return(0); } #ifdef NS_CLONE_NEWIPC singularity_message(DEBUG, "Using IPC namespace: CLONE_NEWIPC\n"); singularity_priv_escalate(); singularity_message(DEBUG, "Virtualizing IPC namespace\n"); if ( unshare(CLONE_NEWIPC) < 0 ) { singularity_message(ERROR, "Could not virtualize IPC namespace: %s\n", strerror(errno)); ABORT(255); } singularity_priv_drop(); enabled = 0; #else singularity_message(WARNING, "Skipping IPC namespace creation, support not available on host\n"); return(0); #endif return(0); }
int singularity_rootfs_mount(void) { char *rootfs_source = joinpath(mount_point, ROOTFS_SOURCE); char *overlay_mount = joinpath(mount_point, OVERLAY_MOUNT); char *overlay_upper = joinpath(mount_point, OVERLAY_UPPER); char *overlay_work = joinpath(mount_point, OVERLAY_WORK); char *overlay_final = joinpath(mount_point, OVERLAY_FINAL); singularity_message(DEBUG, "Checking 'container dir' mount location: %s\n", mount_point); if ( is_dir(mount_point) < 0 ) { singularity_priv_escalate(); singularity_message(VERBOSE, "Creating container dir: %s\n", mount_point); if ( s_mkpath(mount_point, 0755) < 0 ) { singularity_message(ERROR, "Could not create directory: %s\n", mount_point); ABORT(255); } singularity_priv_drop(); } singularity_message(DEBUG, "Checking for rootfs_source directory: %s\n", rootfs_source); if ( is_dir(rootfs_source) < 0 ) { singularity_priv_escalate(); singularity_message(VERBOSE, "Creating container destination dir: %s\n", rootfs_source); if ( s_mkpath(rootfs_source, 0755) < 0 ) { singularity_message(ERROR, "Could not create directory: %s\n", rootfs_source); ABORT(255); } singularity_priv_drop(); } singularity_message(DEBUG, "Checking for overlay_mount directory: %s\n", overlay_mount); if ( is_dir(overlay_mount) < 0 ) { singularity_priv_escalate(); singularity_message(VERBOSE, "Creating container mount dir: %s\n", overlay_mount); if ( s_mkpath(overlay_mount, 0755) < 0 ) { singularity_message(ERROR, "Could not create directory: %s\n", overlay_mount); ABORT(255); } singularity_priv_drop(); } singularity_message(DEBUG, "Checking for overlay_final directory: %s\n", overlay_final); if ( is_dir(overlay_final) < 0 ) { singularity_priv_escalate(); singularity_message(VERBOSE, "Creating overlay final dir: %s\n", overlay_final); if ( s_mkpath(overlay_final, 0755) < 0 ) { singularity_message(ERROR, "Could not create directory: %s\n", overlay_final); ABORT(255); } singularity_priv_drop(); } if ( module == ROOTFS_IMAGE ) { if ( rootfs_image_mount() < 0 ) { singularity_message(ERROR, "Failed mounting image, aborting...\n"); ABORT(255); } } else if ( module == ROOTFS_DIR ) { if ( rootfs_dir_mount() < 0 ) { singularity_message(ERROR, "Failed mounting directory, aborting...\n"); ABORT(255); } } else if ( module == ROOTFS_SQUASHFS ) { if ( rootfs_squashfs_mount() < 0 ) { singularity_message(ERROR, "Failed mounting SquashFS, aborting...\n"); ABORT(255); } } else { singularity_message(ERROR, "Internal error, no rootfs type defined\n"); ABORT(255); } singularity_message(DEBUG, "OverlayFS enabled by host build\n"); if ( singularity_config_get_bool(ENABLE_OVERLAY) <= 0 ) { singularity_message(VERBOSE3, "Not enabling overlayFS via configuration\n"); } else if ( envar_defined("SINGULARITY_DISABLE_OVERLAYFS") == TRUE ) { singularity_message(VERBOSE3, "Not enabling overlayFS via environment\n"); } else if ( envar_defined("SINGULARITY_WRITABLE") == TRUE ) { singularity_message(VERBOSE3, "Not enabling overlayFS, image mounted writablable\n"); } else { #ifdef SINGULARITY_OVERLAYFS int overlay_options_len = strlength(rootfs_source, PATH_MAX) + strlength(overlay_upper, PATH_MAX) + strlength(overlay_work, PATH_MAX) + 50; char *overlay_options = (char *) malloc(overlay_options_len); snprintf(overlay_options, overlay_options_len, "lowerdir=%s,upperdir=%s,workdir=%s", rootfs_source, overlay_upper, overlay_work); // Flawfinder: ignore singularity_priv_escalate(); singularity_message(DEBUG, "Mounting overlay tmpfs: %s\n", overlay_mount); if ( mount("tmpfs", overlay_mount, "tmpfs", MS_NOSUID, "size=1m") < 0 ){ singularity_message(ERROR, "Failed to mount overlay tmpfs %s: %s\n", overlay_mount, strerror(errno)); ABORT(255); } singularity_message(DEBUG, "Creating upper overlay directory: %s\n", overlay_upper); if ( s_mkpath(overlay_upper, 0755) < 0 ) { singularity_message(ERROR, "Failed creating upper overlay directory %s: %s\n", overlay_upper, strerror(errno)); ABORT(255); } singularity_message(DEBUG, "Creating overlay work directory: %s\n", overlay_work); if ( s_mkpath(overlay_work, 0755) < 0 ) { singularity_message(ERROR, "Failed creating overlay work directory %s: %s\n", overlay_work, strerror(errno)); ABORT(255); } singularity_message(VERBOSE, "Mounting overlay with options: %s\n", overlay_options); if ( mount("overlay", overlay_final, "overlay", MS_NOSUID, overlay_options) < 0 ){ singularity_message(ERROR, "Could not create overlay: %s\n", strerror(errno)); ABORT(255); } free(overlay_options); singularity_priv_drop(); overlay_enabled = 1; #else /* SINGULARITY_OVERLAYFS */ singularity_message(WARNING, "OverlayFS not supported by host build\n"); #endif /* SINGULARITY_OVERLAYFS */ } if ( overlay_enabled != 1 ) { singularity_priv_escalate(); singularity_message(VERBOSE3, "Binding the ROOTFS_SOURCE to OVERLAY_FINAL (%s->%s)\n", joinpath(mount_point, ROOTFS_SOURCE), joinpath(mount_point, OVERLAY_FINAL)); if ( mount(joinpath(mount_point, ROOTFS_SOURCE), joinpath(mount_point, OVERLAY_FINAL), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) { singularity_message(ERROR, "There was an error binding the path %s: %s\n", joinpath(mount_point, ROOTFS_SOURCE), strerror(errno)); ABORT(255); } singularity_priv_drop(); } return(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); }
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); }