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_image_mount_squashfs_mount(struct image_object *image, char *mount_point) { if ( image->loopdev == NULL ) { singularity_message(ERROR, "Could not obtain the image loop device\n"); ABORT(255); } singularity_priv_escalate(); singularity_message(VERBOSE, "Mounting squashfs image\n"); if ( mount(image->loopdev, mount_point, "squashfs", MS_NOSUID|MS_RDONLY|MS_NODEV, "errors=remount-ro") < 0 ) { singularity_message(ERROR, "Failed to mount squashfs image in (read only): %s\n", strerror(errno)); ABORT(255); } singularity_priv_drop(); return(0); }
int singularity_rootfs_chroot(void) { singularity_priv_escalate(); singularity_message(VERBOSE, "Entering container file system root: %s\n", joinpath(mount_point, OVERLAY_FINAL)); if ( chroot(joinpath(mount_point, OVERLAY_FINAL)) < 0 ) { // Flawfinder: ignore (yep, yep, yep... we know!) singularity_message(ERROR, "failed enter container at: %s\n", joinpath(mount_point, OVERLAY_FINAL)); ABORT(255); } singularity_priv_drop(); singularity_message(DEBUG, "Changing dir to '/' within the new root\n"); if ( chdir("/") < 0 ) { singularity_message(ERROR, "Could not chdir after chroot to /: %s\n", strerror(errno)); ABORT(1); } return(0); }
pid_t singularity_fork(unsigned int flags) { int priv_fork = 1; prepare_fork(); if ( flags == 0 || geteuid() == 0 ) { priv_fork = 0; } singularity_message(VERBOSE2, "Forking child process\n"); if ( priv_fork == 1 ) { singularity_priv_escalate(); } child_pid = fork_ns(flags); if ( priv_fork == 1 ) { singularity_priv_drop(); } if ( child_pid == 0 ) { singularity_message(VERBOSE2, "Hello from child process\n"); prepare_pipes_child(); singularity_wait_for_go_ahead(); return(child_pid); } else if ( child_pid > 0 ) { singularity_message(VERBOSE2, "Hello from parent process\n"); prepare_pipes_parent(); /* Set signal mask to block all signals while we set up sig actions */ sigset_t blocked_mask, old_mask; sigfillset(&blocked_mask); sigprocmask(SIG_SETMASK, &blocked_mask, &old_mask); /* Now that we can't receive any signals, install signal handlers for all signals we want to catch */ install_generic_signal_handle(); install_sigchld_signal_handle(); /* Set signal mask back to the original mask, unblocking the blocked signals */ sigprocmask(SIG_SETMASK, &old_mask, NULL); /* Set fds[n].fd to the read pipes created earlier */ fds[0].fd = sigchld_signal_rpipe; fds[0].events = POLLIN; fds[0].revents = 0; fds[1].fd = generic_signal_rpipe; fds[1].events = POLLIN; fds[1].revents = 0; /* Drop privs if we're SUID */ if ( singularity_suid_enabled() ) { singularity_message(DEBUG, "Dropping permissions\n"); singularity_priv_drop(); } /* Allow child process to continue */ singularity_signal_go_ahead(0); return(child_pid); } else { singularity_message(ERROR, "Failed to fork child process: %s\n", strerror(errno)); ABORT(255); } }
int _singularity_runtime_mount_binds(void) { char *tmp_config_string; char *container_dir = singularity_runtime_rootfs(NULL); if ( singularity_registry_get("CONTAIN") != NULL ) { singularity_message(DEBUG, "Skipping bind mounts as contain was requested\n"); return(0); } singularity_message(DEBUG, "Checking configuration file for 'bind path'\n"); const char **tmp_config_string_list = singularity_config_get_value_multi(BIND_PATH); if ( strlength(*tmp_config_string_list, 1) == 0 ) { return(0); } while ( *tmp_config_string_list != NULL ) { tmp_config_string = strdup(*tmp_config_string_list); tmp_config_string_list++; char *source = strtok(tmp_config_string, ":"); char *dest = strtok(NULL, ":"); chomp(source); if ( dest == NULL ) { dest = strdup(source); } else { chomp(dest); } singularity_message(VERBOSE2, "Found 'bind path' = %s, %s\n", source, dest); if ( ( is_file(source) < 0 ) && ( is_dir(source) < 0 ) ) { singularity_message(WARNING, "Non existent 'bind path' source: '%s'\n", source); continue; } singularity_message(DEBUG, "Checking if bind point is already mounted: %s\n", dest); if ( check_mounted(dest) >= 0 ) { singularity_message(VERBOSE, "Not mounting bind point (already mounted): %s\n", dest); continue; } if ( ( is_file(source) == 0 ) && ( is_file(joinpath(container_dir, dest)) < 0 ) ) { if ( singularity_registry_get("OVERLAYFS_ENABLED") != NULL ) { char *basedir = dirname(joinpath(container_dir, dest)); singularity_message(DEBUG, "Checking base directory for file %s ('%s')\n", dest, basedir); if ( is_dir(basedir) != 0 ) { singularity_message(DEBUG, "Creating base directory for file bind\n"); singularity_priv_escalate(); if ( s_mkpath(basedir, 0755) != 0 ) { singularity_message(ERROR, "Failed creating base directory to bind file: %s\n", dest); ABORT(255); } singularity_priv_drop(); } free(basedir); singularity_priv_escalate(); singularity_message(VERBOSE3, "Creating bind file on overlay file system: %s\n", dest); FILE *tmp = fopen(joinpath(container_dir, dest), "w+"); // Flawfinder: ignore singularity_priv_drop(); if ( tmp == NULL ) { singularity_message(WARNING, "Could not create bind point file in container %s: %s\n", dest, strerror(errno)); continue; } if ( fclose(tmp) != 0 ) { singularity_message(WARNING, "Could not close bind point file descriptor %s: %s\n", dest, strerror(errno)); continue; } singularity_message(DEBUG, "Created bind file: %s\n", dest); } else { singularity_message(WARNING, "Non existent bind point (file) in container: '%s'\n", dest); continue; } } else if ( ( is_dir(source) == 0 ) && ( is_dir(joinpath(container_dir, dest)) < 0 ) ) { if ( singularity_registry_get("OVERLAYFS_ENABLED") != NULL ) { singularity_priv_escalate(); singularity_message(VERBOSE3, "Creating bind directory on overlay file system: %s\n", dest); if ( s_mkpath(joinpath(container_dir, dest), 0755) < 0 ) { singularity_priv_drop(); singularity_message(WARNING, "Could not create bind point directory in container %s: %s\n", dest, strerror(errno)); continue; } singularity_priv_drop(); } else { singularity_message(WARNING, "Non existent bind point (directory) in container: '%s'\n", dest); continue; } } singularity_priv_escalate(); singularity_message(VERBOSE, "Binding '%s' to '%s/%s'\n", source, container_dir, dest); if ( mount(source, joinpath(container_dir, dest), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) { singularity_message(ERROR, "There was an error binding the path %s: %s\n", source, strerror(errno)); ABORT(255); } if ( singularity_priv_userns_enabled() != 1 ) { if ( mount(NULL, joinpath(container_dir, dest), NULL, MS_BIND|MS_NOSUID|MS_REC|MS_REMOUNT, NULL) < 0 ) { singularity_message(ERROR, "There was an error remounting the path %s: %s\n", source, strerror(errno)); ABORT(255); } } singularity_priv_drop(); } return(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; }
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 _singularity_runtime_mount_tmp(void) { char *container_dir = singularity_runtime_rootfs(NULL); char *tmp_source; char *vartmp_source; if ( singularity_config_get_bool(MOUNT_TMP) <= 0 ) { singularity_message(VERBOSE, "Skipping tmp dir mounting (per config)\n"); return(0); } if ( singularity_registry_get("CONTAIN") == NULL ) { tmp_source = strdup("/tmp"); vartmp_source = strdup("/var/tmp"); } else { char *tmpdirpath; if ( ( tmpdirpath = singularity_registry_get("WORKDIR") ) != NULL ) { if ( singularity_config_get_bool(USER_BIND_CONTROL) <= 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_registry_get("SESSIONDIR"); tmp_source = joinpath(sessiondir, "/tmp"); vartmp_source = joinpath(sessiondir, "/var_tmp"); } free(tmpdirpath); } if ( check_mounted("/tmp") < 0 ) { 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); } if ( singularity_priv_userns_enabled() != 1 ) { if ( mount(NULL, joinpath(container_dir, "/tmp"), NULL, MS_BIND|MS_NOSUID|MS_REC|MS_REMOUNT, NULL) < 0 ) { singularity_message(ERROR, "Failed to remount /tmp: %s\n", 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); } } else { singularity_message(VERBOSE, "Not mounting '/tmp', already mounted\n"); } if ( check_mounted("/var/tmp") < 0 ) { 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); } if ( singularity_priv_userns_enabled() != 1 ) { if ( mount(NULL, joinpath(container_dir, "/var/tmp"), NULL, MS_BIND|MS_NOSUID|MS_REC|MS_REMOUNT, NULL) < 0 ) { singularity_message(ERROR, "Failed to remount /var/tmp: %s\n", 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); } } else { singularity_message(VERBOSE, "Not mounting '/var/tmp', already mounted\n"); } free(tmp_source); free(vartmp_source); return(0); }
int singularity_mount_tmp(void) { char *container_dir = singularity_rootfs_dir(); char *tmp_source; char *vartmp_source; char *tmpdirpath; 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 ( ( tmpdirpath = getenv("SINGULARITY_WORKDIR") ) != NULL ) { // Flawfinder: ignore 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 if ( getenv("SINGULARITY_CONTAIN") != NULL ) { // Flawfinder: ignore char *sessiondir = singularity_sessiondir_get(); tmp_source = joinpath(sessiondir, "/tmp"); vartmp_source = joinpath(sessiondir, "/var_tmp"); } else { tmp_source = strdup("/tmp"); vartmp_source = strdup("/var/tmp"); } if ( s_mkpath(tmp_source, 0755) < 0 ) { singularity_message(ERROR, "Could not create tmp directory %s: %s\n", tmp_source, strerror(errno)); ABORT(255); } if ( s_mkpath(vartmp_source, 0755) < 0 ) { singularity_message(ERROR, "Could not create vartmp directory %s: %s\n", vartmp_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 ( 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); }
int _singularity_runtime_mount_userbinds(void) { char *container_dir = singularity_runtime_rootfs(NULL); char *bind_path_string; singularity_message(DEBUG, "Checking for environment variable 'SINGULARITY_BINDPATH'\n"); if ( ( bind_path_string = singularity_registry_get("BINDPATH") ) != NULL ) { singularity_message(DEBUG, "Checking for 'user bind control' in config\n"); if ( singularity_config_get_bool(USER_BIND_CONTROL) <= 0 ) { singularity_message(WARNING, "Ignoring user bind request: user bind control is disabled by system administrator\n"); return(0); } #ifndef SINGULARITY_NO_NEW_PRIVS singularity_message(WARNING, "Ignoring user bind request: host does not support PR_SET_NO_NEW_PRIVS\n"); return(0); #endif singularity_message(DEBUG, "Parsing SINGULARITY_BINDPATH for user-specified bind mounts.\n"); char *outside_token = NULL; char *inside_token = NULL; char *current = strtok_r(strdup(bind_path_string), ",", &outside_token); free(bind_path_string); while ( current != NULL ) { int read_only = 0; char *source = strtok_r(current, ":", &inside_token); char *dest = strtok_r(NULL, ":", &inside_token); char *opts = strtok_r(NULL, ":", &inside_token); current = strtok_r(NULL, ",", &outside_token); if ( dest == NULL ) { dest = source; } singularity_message(DEBUG, "Found bind: %s -> container:%s\n", source, dest); if ( opts != NULL ) { if ( strcmp(opts, "rw") == 0 ) { // This is the default } else if ( strcmp(opts, "ro") == 0 ) { read_only = 1; } else { singularity_message(WARNING, "Not mounting requested bind point, invalid mount option %s: %s\n", opts, dest); continue; } } singularity_message(DEBUG, "Checking if bind point is already mounted: %s\n", dest); if ( check_mounted(dest) >= 0 ) { singularity_message(WARNING, "Not mounting requested bind point (already mounted in container): %s\n", dest); continue; } if ( ( is_file(source) == 0 ) && ( is_file(joinpath(container_dir, dest)) < 0 ) ) { if ( singularity_registry_get("OVERLAYFS_ENABLED") != NULL ) { char *dir = dirname(strdup(dest)); if ( is_dir(joinpath(container_dir, dir)) < 0 ) { singularity_message(VERBOSE3, "Creating bind directory on overlay file system: %s\n", dest); if ( s_mkpath(joinpath(container_dir, dir), 0755) < 0 ) { singularity_priv_escalate(); singularity_message(VERBOSE3, "Retrying with privileges to create bind directory on overlay file system: %s\n", dest); if ( s_mkpath(joinpath(container_dir, dir), 0755) < 0 ) { singularity_message(ERROR, "Could not create basedir for file bind %s: %s\n", dest, strerror(errno)); continue; } singularity_priv_drop(); } } singularity_priv_escalate(); singularity_message(VERBOSE3, "Creating bind file on overlay file system: %s\n", dest); FILE *tmp = fopen(joinpath(container_dir, dest), "w+"); // Flawfinder: ignore singularity_priv_drop(); if ( tmp == NULL ) { singularity_message(WARNING, "Skipping user bind, could not create bind point %s: %s\n", dest, strerror(errno)); continue; } if ( fclose(tmp) != 0 ) { singularity_message(WARNING, "Skipping user bind, could not close bind point file descriptor %s: %s\n", dest, strerror(errno)); continue; } singularity_message(DEBUG, "Created bind file: %s\n", dest); } else { singularity_message(WARNING, "Skipping user bind, non existant bind point (file) in container: '%s'\n", dest); continue; } } else if ( ( is_dir(source) == 0 ) && ( is_dir(joinpath(container_dir, dest)) < 0 ) ) { if ( singularity_registry_get("OVERLAYFS_ENABLED") != NULL ) { singularity_message(VERBOSE3, "Creating bind directory on overlay file system: %s\n", dest); if ( s_mkpath(joinpath(container_dir, dest), 0755) < 0 ) { singularity_priv_escalate(); singularity_message(VERBOSE3, "Retrying with privileges to create bind directory on overlay file system: %s\n", dest); if ( s_mkpath(joinpath(container_dir, dest), 0755) < 0 ) { singularity_priv_drop(); singularity_message(WARNING, "Skipping user bind, could not create bind point %s: %s\n", dest, strerror(errno)); continue; } singularity_priv_drop(); } } else { singularity_message(WARNING, "Skipping user bind, non existant bind point (directory) in container: '%s'\n", dest); continue; } } singularity_priv_escalate(); singularity_message(VERBOSE, "Binding '%s' to '%s/%s'\n", source, container_dir, dest); if ( mount(source, joinpath(container_dir, dest), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) { singularity_message(ERROR, "There was an error binding the path %s: %s\n", source, strerror(errno)); ABORT(255); } if ( read_only ) { if ( singularity_priv_userns_enabled() == 1 ) { singularity_message(WARNING, "Can not make bind mount read only within the user namespace: %s\n", dest); } else { singularity_message(VERBOSE, "Remounting %s read-only\n", dest); if ( mount(NULL, joinpath(container_dir, dest), NULL, MS_RDONLY|MS_BIND|MS_NOSUID|MS_REC|MS_REMOUNT, NULL) < 0 ) { singularity_message(ERROR, "There was an error write-protecting the path %s: %s\n", source, strerror(errno)); ABORT(255); } if ( access(joinpath(container_dir, dest), W_OK) == 0 || errno != EROFS ) { // Flawfinder: ignore (precautionary confirmation, not necessary) singularity_message(ERROR, "Failed to write-protect the path %s: %s\n", source, strerror(errno)); ABORT(255); } } } else { if ( singularity_priv_userns_enabled() <= 0 ) { if ( mount(NULL, joinpath(container_dir, dest), NULL, MS_BIND|MS_NOSUID|MS_REC|MS_REMOUNT, NULL) < 0 ) { singularity_message(ERROR, "There was an error remounting the path %s: %s\n", source, strerror(errno)); ABORT(255); } } } singularity_priv_drop(); } singularity_message(DEBUG, "Unsetting environment variable 'SINGULARITY_BINDPATH'\n"); unsetenv("SINGULARITY_BINDPATH"); } else { singularity_message(DEBUG, "No user bind mounts specified.\n"); } return(0); }
int singularity_mount_kernelfs(void) { char *container_dir = singularity_rootfs_dir(); // Mount /proc if we are configured singularity_message(DEBUG, "Checking configuration file for 'mount proc'\n"); singularity_config_rewind(); if ( singularity_config_get_bool("mount proc", 1) > 0 ) { if ( is_dir(joinpath(container_dir, "/proc")) == 0 ) { if ( singularity_ns_pid_enabled() >= 0 ) { singularity_priv_escalate(); singularity_message(VERBOSE, "Mounting /proc\n"); if ( mount("proc", joinpath(container_dir, "/proc"), "proc", 0, NULL) < 0 ) { singularity_message(ERROR, "Could not mount /proc into container: %s\n", strerror(errno)); ABORT(255); } singularity_priv_drop(); } else { singularity_priv_escalate(); singularity_message(VERBOSE, "Bind mounting /proc\n"); if ( mount("/proc", joinpath(container_dir, "/proc"), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) { singularity_message(ERROR, "Could not bind mount container's /proc: %s\n", strerror(errno)); ABORT(255); } singularity_priv_drop(); } } else { singularity_message(WARNING, "Not mounting /proc, container has no bind directory\n"); } } else { singularity_message(VERBOSE, "Skipping /proc mount\n"); } // Mount /sys if we are configured singularity_message(DEBUG, "Checking configuration file for 'mount sys'\n"); singularity_config_rewind(); if ( singularity_config_get_bool("mount sys", 1) > 0 ) { if ( is_dir(joinpath(container_dir, "/sys")) == 0 ) { if ( singularity_ns_user_enabled() < 0 ) { singularity_priv_escalate(); singularity_message(VERBOSE, "Mounting /sys\n"); if ( mount("sysfs", joinpath(container_dir, "/sys"), "sysfs", 0, NULL) < 0 ) { singularity_message(ERROR, "Could not mount /sys into container: %s\n", strerror(errno)); ABORT(255); } singularity_priv_drop(); } else { singularity_priv_escalate(); singularity_message(VERBOSE, "Bind mounting /sys\n"); if ( mount("/sys", joinpath(container_dir, "/sys"), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) { singularity_message(ERROR, "Could not bind mount container's /sys: %s\n", strerror(errno)); ABORT(255); } singularity_priv_drop(); } } else { singularity_message(WARNING, "Not mounting /sys, container has no bind directory\n"); } } else { singularity_message(VERBOSE, "Skipping /sys mount\n"); } return(0); }