char * container_basedir(char *containerdir, char *dir) { char * testdir = strdup(dir); char * prevdir = NULL; if ( containerdir == NULL || dir == NULL ) { return(NULL); } while ( testdir != NULL && ( strcmp(testdir, "/") != 0 ) ) { if ( is_dir(joinpath(containerdir, testdir)) == 0 ) { return(testdir); } prevdir = strdup(testdir); testdir = dirname(strdup(testdir)); } return(prevdir); }
static void calculate_exec_prefix(const _PyCoreConfig *core_config, PyCalculatePath *calculate, wchar_t *exec_prefix) { calculate->exec_prefix_found = search_for_exec_prefix(core_config, calculate, exec_prefix); if (!calculate->exec_prefix_found) { if (!core_config->_frozen) { fprintf(stderr, "Could not find platform dependent libraries <exec_prefix>\n"); } wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN); joinpath(exec_prefix, L"lib/lib-dynload"); } /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ }
static void calculate_prefix(const _PyCoreConfig *core_config, PyCalculatePath *calculate, wchar_t *prefix) { calculate->prefix_found = search_for_prefix(core_config, calculate, prefix); if (!calculate->prefix_found) { if (!core_config->_frozen) { fprintf(stderr, "Could not find platform independent libraries <prefix>\n"); } wcsncpy(prefix, calculate->prefix, MAXPATHLEN); joinpath(prefix, calculate->lib_python); } else { reduce(prefix); } }
int check_mounted(char *mountpoint) { int retval = -1; FILE *mounts; char *line = (char *)malloc(MAX_LINE_LEN); char *rootfs_dir = singularity_runtime_rootfs(NULL); unsigned int mountpoint_len = strlength(mountpoint, PATH_MAX); singularity_message(DEBUG, "Opening /proc/mounts\n"); if ( ( mounts = fopen("/proc/mounts", "r") ) == NULL ) { // Flawfinder: ignore singularity_message(ERROR, "Could not open /proc/mounts: %s\n", strerror(errno)); ABORT(255); } if ( mountpoint[mountpoint_len-1] == '/' ) { singularity_message(DEBUG, "Removing trailing slash from string: %s\n", mountpoint); mountpoint[mountpoint_len-1] = '\0'; } singularity_message(DEBUG, "Iterating through /proc/mounts\n"); while ( fgets(line, MAX_LINE_LEN, mounts) != NULL ) { (void) strtok(strdup(line), " "); char *mount = strtok(NULL, " "); // Check to see if path is in container root if ( strncmp(rootfs_dir, mount, strlength(rootfs_dir, 1024)) != 0 ) { continue; } // Check to see if path is ot the container root if ( strcmp(mount, rootfs_dir) == 0 ) { continue; } // Check to see if mountpoint is already mounted if ( strcmp(joinpath(rootfs_dir, mountpoint), mount) == 0 ) { singularity_message(DEBUG, "Mountpoint is already mounted: %s\n", mountpoint); retval = 1; break; } } fclose(mounts); free(line); return(retval); }
/* search_for_exec_prefix requires that argv0_path be no more than MAXPATHLEN bytes long. */ static int search_for_exec_prefix(char *argv0_path, char *home) { size_t n; /* If PYTHONHOME is set, we believe it unconditionally */ if (home) { char *delim; delim = strchr(home, DELIM); if (delim) strncpy(exec_prefix, delim+1, MAXPATHLEN); else strncpy(exec_prefix, home, MAXPATHLEN); joinpath(exec_prefix, lib_python); joinpath(exec_prefix, "lib-dynload"); return 1; } /* Check to see if argv[0] is in the build directory */ strcpy(exec_prefix, argv0_path); joinpath(exec_prefix, "Modules/Setup"); if (isfile(exec_prefix)) { reduce(exec_prefix); return -1; } /* Search from argv0_path, until root is found */ copy_absolute(exec_prefix, argv0_path); do { n = strlen(exec_prefix); joinpath(exec_prefix, lib_python); joinpath(exec_prefix, "lib-dynload"); if (isdir(exec_prefix)) return 1; exec_prefix[n] = '\0'; reduce(exec_prefix); } while (exec_prefix[0]); /* Look at configure's EXEC_PREFIX */ strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN); joinpath(exec_prefix, lib_python); joinpath(exec_prefix, "lib-dynload"); if (isdir(exec_prefix)) return 1; /* Fail */ return 0; }
/* copy_absolute requires that path be allocated at least MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */ static void copy_absolute(wchar_t *path, wchar_t *p, size_t pathlen) { if (p[0] == SEP) { wcscpy(path, p); } else { if (!_Py_wgetcwd(path, pathlen)) { /* unable to get the current directory */ wcscpy(path, p); return; } if (p[0] == '.' && p[1] == SEP) { p += 2; } joinpath(path, p); } }
static void calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix) { wcsncpy(calculate->zip_path, prefix, MAXPATHLEN); calculate->zip_path[MAXPATHLEN] = L'\0'; if (calculate->prefix_found > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */ reduce(calculate->zip_path); reduce(calculate->zip_path); } else { wcsncpy(calculate->zip_path, calculate->prefix, MAXPATHLEN); } joinpath(calculate->zip_path, L"lib/python00.zip"); /* Replace "00" with version */ size_t bufsz = wcslen(calculate->zip_path); calculate->zip_path[bufsz - 6] = VERSION[0]; calculate->zip_path[bufsz - 5] = VERSION[2]; }
int container_daemon_stop(char *sessiondir) { FILE *comm; FILE *test_daemon_fp; int daemon_fd; message(DEBUG, "Called container_daemon_stop(%s)\n", sessiondir); message(VERBOSE, "Checking if daemon is currently running for this container\n"); if ( is_file(joinpath(sessiondir, "daemon.pid")) < 0 ) { message(ERROR, "Daemon process is not running\n"); return(0); } message(DEBUG, "Opening daemon.pid for reading\n"); if ( ( test_daemon_fp = fopen(joinpath(sessiondir, "daemon.pid"), "r") ) == NULL ) { // Flawfinder: ignore message(ERROR, "Could not open daemon pid file %s: %s\n", joinpath(sessiondir, "daemon.pid"), strerror(errno)); ABORT(255); } message(DEBUG, "Testing to see if daemon process is still active\n"); daemon_fd = fileno(test_daemon_fp); if ( flock(daemon_fd, LOCK_SH | LOCK_NB) == 0 ) { message(INFO, "No active container daemon active\n"); return(0); } message(DEBUG, "Connecting to daemon.comm FIFO\n"); if ( is_fifo(joinpath(sessiondir, "daemon.comm")) < 0 ) { message(ERROR, "Container daemon COMM not available\n"); ABORT(255); } message(VERBOSE, "Opening daemon.comm for writing\n"); if ( ( comm = fopen(joinpath(sessiondir, "daemon.comm"), "w") ) == NULL ) { //Flawfinder: ignore message(ERROR, "Could not open fifo for writing %s: %s\n", joinpath(sessiondir, "daemon.comm"), strerror(errno)); ABORT(255); } message(VERBOSE, "Sending stop command to daemon process\n"); fputs("stop", comm); fclose(comm); message(DEBUG, "Return container_daemon_stop(%s) = 0\n", sessiondir); return(0); }
int git2_mkdir_2file(const char *file_path) { const int mode = 0755; /* or 0777 ? */ int error = GIT_OK; char target_folder_path[GIT_PATH_MAX]; error = dirname_r(target_folder_path, sizeof(target_folder_path), file_path); if (error < GIT_OK) return GIT_ERROR; /* Does the containing folder exist? */ if (git2_isdir(target_folder_path)) { joinpath(target_folder_path, target_folder_path, ""); /* Ensure there's a trailing slash */ /* Let's create the tree structure */ error = git2_mkdir_recurs(target_folder_path, mode); if (error < GIT_OK) return error; /* The callee already takes care of setting the correct error message. */ } return GIT_OK; }
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); }
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); }
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; }
char *singularity_rootfs_dir(void) { singularity_message(DEBUG, "Returning singularity_rootfs_dir: %s\n", joinpath(mount_point, OVERLAY_FINAL)); return(joinpath(mount_point, OVERLAY_FINAL)); }
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); }
/* * rewrite .newsrc and position group at specifed position */ t_bool pos_group_in_newsrc( struct t_group *group, int pos) { FILE *fp_in = NULL, *fp_out = NULL; FILE *fp_sub = NULL, *fp_unsub = NULL; char *newsgroup = NULL; char *line; char buf[HEADER_LEN]; char sub[HEADER_LEN]; char unsub[HEADER_LEN]; int subscribed_pos = 1; size_t group_len; t_bool found = FALSE; t_bool newnewsrc_created = FALSE; t_bool option_line = FALSE; t_bool repositioned = FALSE; t_bool ret_code = FALSE; t_bool sub_created = FALSE; t_bool unsub_created = FALSE; if (no_write) goto rewrite_group_done; if ((fp_in = fopen(newsrc, "r")) == NULL) goto rewrite_group_done; if ((fp_out = fopen(newnewsrc, "w" FOPEN_OPTS)) == NULL) goto rewrite_group_done; newnewsrc_created = TRUE; #ifndef M_OS2 if (newsrc_mode) fchmod(fileno(fp_out), newsrc_mode); #endif /* !M_OS2 */ #ifdef VMS joinpath(buf, TMPDIR, "subrc"); sprintf(sub, "%s.%d", buf, (int) process_id); joinpath(buf, TMPDIR, "unsubrc"); sprintf(unsub, "%s.%d", buf, (int) process_id); #else joinpath(buf, TMPDIR, ".subrc"); sprintf(sub, "%s.%d", buf, (int) process_id); joinpath(buf, TMPDIR, ".unsubrc"); sprintf(unsub, "%s.%d", buf, (int) process_id); #endif /* !VMS */ if ((fp_sub = fopen(sub, "w" FOPEN_OPTS)) == NULL) goto rewrite_group_done; sub_created = TRUE; if ((fp_unsub = fopen(unsub, "w" FOPEN_OPTS)) == NULL) goto rewrite_group_done; unsub_created = TRUE; /* * split newsrc into subscribed and unsubscribed to files */ group_len = strlen(group->name); while ((line = tin_fgets(fp_in, FALSE)) != NULL) { if (STRNCMPEQ(group->name, line, group_len) && line[group_len] == SUBSCRIBED) { newsgroup = my_strdup(line); /* Take a copy of this line */ found = TRUE; continue; } else if (strchr(line, SUBSCRIBED) != NULL) { write_newsrc_line(fp_sub, line); } else if (strchr(line, UNSUBSCRIBED) != NULL) { write_newsrc_line(fp_unsub, line); } else { /* options line at beginning of .newsrc */ fprintf(fp_sub, "%s\n", line); option_line = TRUE; } } if (ferror(fp_sub) || fclose(fp_sub) || ferror(fp_unsub) || fclose(fp_unsub)) { error_message(_(txt_filesystem_full), NEWSRC_FILE); fp_sub = fp_unsub = NULL; goto rewrite_group_done; } fp_sub = fp_unsub = NULL; fclose(fp_in); fp_in = NULL; /* * The group to be moved cannot be found, so give up now */ if (!found) goto rewrite_group_done; /* * write subscribed groups & repositioned group to newnewsrc */ if ((fp_sub = fopen(sub, "r")) == NULL) goto rewrite_group_done; while ((line = tin_fgets(fp_sub, FALSE)) != NULL) { if (option_line) { if (strchr(line, SUBSCRIBED) == NULL && strchr(line, UNSUBSCRIBED) == NULL) { fprintf(fp_out, "%s\n", line); continue; } else option_line = FALSE; } if (pos == subscribed_pos) { write_newsrc_line(fp_out, newsgroup); repositioned = TRUE; } fprintf(fp_out, "%s\n", line); subscribed_pos++; } if (!repositioned) { write_newsrc_line(fp_out, newsgroup); repositioned = TRUE; } /* * append unsubscribed groups file to newnewsrc */ if ((fp_unsub = fopen(unsub, "r")) == NULL) goto rewrite_group_done; while ((line = tin_fgets(fp_unsub, FALSE)) != NULL) fprintf(fp_out, "%s\n", line); /* * Try and cleanly close out the newnewsrc file */ if (ferror(fp_out) || fclose(fp_out)) error_message(_(txt_filesystem_full), NEWSRC_FILE); else { if (repositioned) { rename_file(newnewsrc, newsrc); ret_code = TRUE; } } fp_out = NULL; newnewsrc_created = FALSE; rewrite_group_done: if (fp_in != NULL) fclose(fp_in); if (fp_out != NULL) fclose(fp_out); if (fp_sub != NULL) fclose(fp_sub); if (fp_unsub != NULL) fclose(fp_unsub); if (newnewsrc_created) unlink(newnewsrc); if (sub_created) unlink(sub); if (unsub_created) unlink(unsub); FreeIfNeeded(newsgroup); return ret_code; }
void msg_write_signature( FILE *fp, t_bool include_dot_signature, struct t_group *thisgroup) { FILE *fixfp; FILE *sigfp; char cwd[PATH_LEN]; char path[PATH_LEN]; char pathfixed[PATH_LEN]; #ifdef NNTP_INEWS if (read_news_via_nntp && 0 == strcasecmp(tinrc.inews_prog, INTERNAL_CMD)) include_dot_signature = TRUE; #endif /* NNTP_INEWS */ if (thisgroup && !thisgroup->bogus) { if (!strcmp(thisgroup->attribute->sigfile, "--none")) return; /* TODO: handle DONT_HAVE_PIPING case */ #ifndef DONT_HAVE_PIPING if (thisgroup->attribute->sigfile[0] == '!') { FILE *pipe_fp; char *sigcmd; char cmd[PATH_LEN]; fprintf(fp, "\n%s", tinrc.sigdashes ? SIGDASHES : "\n"); sigcmd = my_malloc(strlen(thisgroup->attribute->sigfile + 1) + strlen(thisgroup->name) + 4); sprintf(sigcmd, "%s \"%s\"", thisgroup->attribute->sigfile + 1, thisgroup->name); if ((pipe_fp = popen(sigcmd, "r")) != NULL) { while (fgets(cmd, PATH_LEN, pipe_fp)) fputs(cmd, fp); pclose(pipe_fp); } /* else issue an error-message? */ free(sigcmd); return; } #endif /* !DONT_HAVE_PIPING */ get_cwd(cwd); if (!strfpath(thisgroup->attribute->sigfile, path, sizeof(path), thisgroup)) { if (!strfpath(tinrc.sigfile, path, sizeof(path), thisgroup)) joinpath(path, homedir, ".Sig"); } /* * Check to see if sigfile is a directory & if it is * generate a random signature from sigs in sigdir. If * the file path/.sigfixed or ~/.sigfixed exists (fixed * part of random sig) then read it in first and append * the random sig part onto the end. */ if ((sigfp = open_random_sig(path)) != NULL) { #ifdef DEBUG if (debug == 2) error_message("USING random sig=[%s]", sigfile); #endif /* DEBUG */ fprintf(fp, "\n%s", tinrc.sigdashes ? SIGDASHES : "\n"); joinpath(pathfixed, path, ".sigfixed"); #ifdef DEBUG if (debug == 2) error_message("TRYING fixed sig=[%s]", pathfixed); #endif /* DEBUG */ if ((fixfp = fopen(pathfixed, "r")) != NULL) { copy_fp(fixfp, fp); fclose(fixfp); } else { joinpath(pathfixed, homedir, ".sigfixed"); #ifdef DEBUG if (debug == 2) error_message("TRYING fixed sig=[%s]", pathfixed); #endif /* DEBUG */ if ((fixfp = fopen(pathfixed, "r")) != NULL) { copy_fp(fixfp, fp); fclose(fixfp); } } copy_fp(sigfp, fp); fclose(sigfp); my_chdir(cwd); return; } } if ((sigfp = fopen(path, "r")) != NULL) { fprintf(fp, "\n%s", tinrc.sigdashes ? SIGDASHES : "\n"); copy_fp(sigfp, fp); fclose(sigfp); return; } /* * Use ~/.signature as a last resort, but only if mailing or * using internal inews (external inews appends it automagically). */ if ((sigfp = fopen(default_signature, "r")) != NULL) { if (include_dot_signature) { fprintf(fp, "\n%s", tinrc.sigdashes ? SIGDASHES : "\n"); copy_fp(sigfp, fp); } fclose(sigfp); } }
/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN bytes long. */ static int search_for_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix) { size_t n; wchar_t *vpath; /* If PYTHONHOME is set, we believe it unconditionally */ if (home) { wchar_t *delim; wcsncpy(prefix, home, MAXPATHLEN); prefix[MAXPATHLEN] = L'\0'; delim = wcschr(prefix, DELIM); if (delim) *delim = L'\0'; joinpath(prefix, lib_python); joinpath(prefix, LANDMARK); return 1; } /* Check to see if argv[0] is in the build directory */ wcsncpy(prefix, argv0_path, MAXPATHLEN); prefix[MAXPATHLEN] = L'\0'; joinpath(prefix, L"Modules/Setup"); if (isfile(prefix)) { /* Check VPATH to see if argv0_path is in the build directory. */ vpath = _Py_char2wchar(VPATH, NULL); if (vpath != NULL) { wcsncpy(prefix, argv0_path, MAXPATHLEN); prefix[MAXPATHLEN] = L'\0'; joinpath(prefix, vpath); PyMem_RawFree(vpath); joinpath(prefix, L"Lib"); joinpath(prefix, LANDMARK); if (ismodule(prefix)) return -1; } } /* Search from argv0_path, until root is found */ copy_absolute(prefix, argv0_path, MAXPATHLEN+1); do { n = wcslen(prefix); joinpath(prefix, lib_python); joinpath(prefix, LANDMARK); if (ismodule(prefix)) return 1; prefix[n] = L'\0'; reduce(prefix); } while (prefix[0]); /* Look at configure's PREFIX */ wcsncpy(prefix, _prefix, MAXPATHLEN); prefix[MAXPATHLEN] = L'\0'; joinpath(prefix, lib_python); joinpath(prefix, LANDMARK); if (ismodule(prefix)) return 1; /* Fail */ return 0; }
static void calculate_path(void) { extern char *Py_GetProgramName(void); static char delimiter[2] = {DELIM, '\0'}; static char separator[2] = {SEP, '\0'}; char *pythonpath = PYTHONPATH; char *rtpypath = Py_GETENV("PYTHONPATH"); char *home = Py_GetPythonHome(); char *path = getenv("PATH"); char *prog = Py_GetProgramName(); char argv0_path[MAXPATHLEN+1]; char zip_path[MAXPATHLEN+1]; int pfound, efound; /* 1 if found; -1 if found build directory */ char *buf; size_t bufsz; size_t prefixsz; char *defpath = pythonpath; #ifdef WITH_NEXT_FRAMEWORK NSModule pythonModule; #endif /* If there is no slash in the argv0 path, then we have to * assume python is on the user's $PATH, since there's no * other way to find a directory to start the search from. If * $PATH isn't exported, you lose. */ if (strchr(prog, SEP)) strncpy(progpath, prog, MAXPATHLEN); else if (path) { while (1) { char *delim = strchr(path, DELIM); if (delim) { size_t len = delim - path; if (len > MAXPATHLEN) len = MAXPATHLEN; strncpy(progpath, path, len); *(progpath + len) = '\0'; } else strncpy(progpath, path, MAXPATHLEN); joinpath(progpath, prog); if (isxfile(progpath)) break; if (!delim) { progpath[0] = '\0'; break; } path = delim + 1; } } else progpath[0] = '\0'; if (progpath[0] != SEP) absolutize(progpath); strncpy(argv0_path, progpath, MAXPATHLEN); argv0_path[MAXPATHLEN] = '\0'; #ifdef WITH_NEXT_FRAMEWORK /* On Mac OS X we have a special case if we're running from a framework. ** This is because the python home should be set relative to the library, ** which is in the framework, not relative to the executable, which may ** be outside of the framework. Except when we're in the build directory... */ pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize")); /* Use dylib functions to find out where the framework was loaded from */ buf = (char *)NSLibraryNameForModule(pythonModule); if (buf != NULL) { /* We're in a framework. */ /* See if we might be in the build directory. The framework in the ** build directory is incomplete, it only has the .dylib and a few ** needed symlinks, it doesn't have the Lib directories and such. ** If we're running with the framework from the build directory we must ** be running the interpreter in the build directory, so we use the ** build-directory-specific logic to find Lib and such. */ strncpy(argv0_path, buf, MAXPATHLEN); reduce(argv0_path); joinpath(argv0_path, lib_python); joinpath(argv0_path, LANDMARK); if (!ismodule(argv0_path)) { /* We are in the build directory so use the name of the executable - we know that the absolute path is passed */ strncpy(argv0_path, prog, MAXPATHLEN); } else { /* Use the location of the library as the progpath */ strncpy(argv0_path, buf, MAXPATHLEN); } } #endif #if HAVE_READLINK { char tmpbuffer[MAXPATHLEN+1]; int linklen = readlink(progpath, tmpbuffer, MAXPATHLEN); while (linklen != -1) { /* It's not null terminated! */ tmpbuffer[linklen] = '\0'; if (tmpbuffer[0] == SEP) /* tmpbuffer should never be longer than MAXPATHLEN, but extra check does not hurt */ strncpy(argv0_path, tmpbuffer, MAXPATHLEN); else { /* Interpret relative to progpath */ reduce(argv0_path); joinpath(argv0_path, tmpbuffer); } linklen = readlink(argv0_path, tmpbuffer, MAXPATHLEN); } } #endif /* HAVE_READLINK */ reduce(argv0_path); /* At this point, argv0_path is guaranteed to be less than MAXPATHLEN bytes long. */ if (!(pfound = search_for_prefix(argv0_path, home))) { if (!Py_FrozenFlag) fprintf(stderr, "Could not find platform independent libraries <prefix>\n"); strncpy(prefix, PREFIX, MAXPATHLEN); joinpath(prefix, lib_python); } else reduce(prefix); strncpy(zip_path, prefix, MAXPATHLEN); zip_path[MAXPATHLEN] = '\0'; if (pfound > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */ reduce(zip_path); reduce(zip_path); } else strncpy(zip_path, PREFIX, MAXPATHLEN); joinpath(zip_path, "lib/python00.zip"); bufsz = strlen(zip_path); /* Replace "00" with version */ zip_path[bufsz - 6] = VERSION[0]; zip_path[bufsz - 5] = VERSION[2]; if (!(efound = search_for_exec_prefix(argv0_path, home))) { if (!Py_FrozenFlag) fprintf(stderr, "Could not find platform dependent libraries <exec_prefix>\n"); strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN); joinpath(exec_prefix, "lib/lib-dynload"); } /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ if ((!pfound || !efound) && !Py_FrozenFlag) fprintf(stderr, "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n"); /* Calculate size of return buffer. */ bufsz = 0; if (rtpypath) bufsz += strlen(rtpypath) + 1; prefixsz = strlen(prefix) + 1; while (1) { char *delim = strchr(defpath, DELIM); if (defpath[0] != SEP) /* Paths are relative to prefix */ bufsz += prefixsz; if (delim) bufsz += delim - defpath + 1; else { bufsz += strlen(defpath) + 1; break; } defpath = delim + 1; } bufsz += strlen(zip_path) + 1; bufsz += strlen(exec_prefix) + 1; /* This is the only malloc call in this file */ buf = PyMem_Malloc(bufsz); if (buf == NULL) { /* We can't exit, so print a warning and limp along */ fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n"); fprintf(stderr, "Using default static PYTHONPATH.\n"); module_search_path = PYTHONPATH; } else { /* Run-time value of $PYTHONPATH goes first */ if (rtpypath) { strcpy(buf, rtpypath); strcat(buf, delimiter); } else buf[0] = '\0'; /* Next is the default zip path */ strcat(buf, zip_path); strcat(buf, delimiter); /* Next goes merge of compile-time $PYTHONPATH with * dynamically located prefix. */ defpath = pythonpath; while (1) { char *delim = strchr(defpath, DELIM); if (defpath[0] != SEP) { strcat(buf, prefix); strcat(buf, separator); } if (delim) { size_t len = delim - defpath + 1; size_t end = strlen(buf) + len; strncat(buf, defpath, len); *(buf + end) = '\0'; } else { strcat(buf, defpath); break; } defpath = delim + 1; } strcat(buf, delimiter); /* Finally, on goes the directory for dynamic-load modules */ strcat(buf, exec_prefix); /* And publish the results */ module_search_path = buf; } /* Reduce prefix and exec_prefix to their essence, * e.g. /usr/local/lib/python1.5 is reduced to /usr/local. * If we're loading relative to the build directory, * return the compiled-in defaults instead. */ if (pfound > 0) { reduce(prefix); reduce(prefix); } else strncpy(prefix, PREFIX, MAXPATHLEN); if (efound > 0) { reduce(exec_prefix); reduce(exec_prefix); reduce(exec_prefix); } else strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN); }
static void calculate_path(void) { extern wchar_t *Py_GetProgramName(void); static wchar_t delimiter[2] = {DELIM, '\0'}; static wchar_t separator[2] = {SEP, '\0'}; char *_rtpypath = Py_GETENV("PYTHONPATH"); /* XXX use wide version on Windows */ wchar_t rtpypath[MAXPATHLEN+1]; wchar_t *home = Py_GetPythonHome(); char *_path = getenv("PATH"); wchar_t *path_buffer = NULL; wchar_t *path = NULL; wchar_t *prog = Py_GetProgramName(); wchar_t argv0_path[MAXPATHLEN+1]; wchar_t zip_path[MAXPATHLEN+1]; int pfound, efound; /* 1 if found; -1 if found build directory */ wchar_t *buf; size_t bufsz; size_t prefixsz; wchar_t *defpath; #ifdef WITH_NEXT_FRAMEWORK NSModule pythonModule; #endif #ifdef __APPLE__ #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 uint32_t nsexeclength = MAXPATHLEN; #else unsigned long nsexeclength = MAXPATHLEN; #endif char execpath[MAXPATHLEN+1]; #endif wchar_t *_pythonpath, *_prefix, *_exec_prefix; _pythonpath = _Py_char2wchar(PYTHONPATH, NULL); _prefix = _Py_char2wchar(PREFIX, NULL); _exec_prefix = _Py_char2wchar(EXEC_PREFIX, NULL); if (!_pythonpath || !_prefix || !_exec_prefix) { Py_FatalError( "Unable to decode path variables in getpath.c: " "memory error"); } if (_path) { path_buffer = _Py_char2wchar(_path, NULL); path = path_buffer; } /* If there is no slash in the argv0 path, then we have to * assume python is on the user's $PATH, since there's no * other way to find a directory to start the search from. If * $PATH isn't exported, you lose. */ if (wcschr(prog, SEP)) wcsncpy(progpath, prog, MAXPATHLEN); #ifdef __APPLE__ /* On Mac OS X, if a script uses an interpreter of the form * "#!/opt/python2.3/bin/python", the kernel only passes "python" * as argv[0], which falls through to the $PATH search below. * If /opt/python2.3/bin isn't in your path, or is near the end, * this algorithm may incorrectly find /usr/bin/python. To work * around this, we can use _NSGetExecutablePath to get a better * hint of what the intended interpreter was, although this * will fail if a relative path was used. but in that case, * absolutize() should help us out below */ else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) && execpath[0] == SEP) { size_t r = mbstowcs(progpath, execpath, MAXPATHLEN+1); if (r == (size_t)-1 || r > MAXPATHLEN) { /* Could not convert execpath, or it's too long. */ progpath[0] = '\0'; } } #endif /* __APPLE__ */ else if (path) { while (1) { wchar_t *delim = wcschr(path, DELIM); if (delim) { size_t len = delim - path; if (len > MAXPATHLEN) len = MAXPATHLEN; wcsncpy(progpath, path, len); *(progpath + len) = '\0'; } else wcsncpy(progpath, path, MAXPATHLEN); joinpath(progpath, prog); if (isxfile(progpath)) break; if (!delim) { progpath[0] = L'\0'; break; } path = delim + 1; } } else progpath[0] = '\0'; if (path_buffer != NULL) PyMem_Free(path_buffer); if (progpath[0] != SEP && progpath[0] != '\0') absolutize(progpath); wcsncpy(argv0_path, progpath, MAXPATHLEN); argv0_path[MAXPATHLEN] = '\0'; #ifdef WITH_NEXT_FRAMEWORK /* On Mac OS X we have a special case if we're running from a framework. ** This is because the python home should be set relative to the library, ** which is in the framework, not relative to the executable, which may ** be outside of the framework. Except when we're in the build directory... */ pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize")); /* Use dylib functions to find out where the framework was loaded from */ buf = (wchar_t *)NSLibraryNameForModule(pythonModule); if (buf != NULL) { /* We're in a framework. */ /* See if we might be in the build directory. The framework in the ** build directory is incomplete, it only has the .dylib and a few ** needed symlinks, it doesn't have the Lib directories and such. ** If we're running with the framework from the build directory we must ** be running the interpreter in the build directory, so we use the ** build-directory-specific logic to find Lib and such. */ wcsncpy(argv0_path, buf, MAXPATHLEN); reduce(argv0_path); joinpath(argv0_path, lib_python); joinpath(argv0_path, LANDMARK); if (!ismodule(argv0_path)) { /* We are in the build directory so use the name of the executable - we know that the absolute path is passed */ wcsncpy(argv0_path, progpath, MAXPATHLEN); } else { /* Use the location of the library as the progpath */ wcsncpy(argv0_path, buf, MAXPATHLEN); } } #endif #if HAVE_READLINK { wchar_t tmpbuffer[MAXPATHLEN+1]; int linklen = _Py_wreadlink(progpath, tmpbuffer, MAXPATHLEN); while (linklen != -1) { if (tmpbuffer[0] == SEP) /* tmpbuffer should never be longer than MAXPATHLEN, but extra check does not hurt */ wcsncpy(argv0_path, tmpbuffer, MAXPATHLEN); else { /* Interpret relative to progpath */ reduce(argv0_path); joinpath(argv0_path, tmpbuffer); } linklen = _Py_wreadlink(argv0_path, tmpbuffer, MAXPATHLEN); } } #endif /* HAVE_READLINK */ reduce(argv0_path); /* At this point, argv0_path is guaranteed to be less than MAXPATHLEN bytes long. */ if (!(pfound = search_for_prefix(argv0_path, home, _prefix))) { if (!Py_FrozenFlag) fprintf(stderr, "Could not find platform independent libraries <prefix>\n"); wcsncpy(prefix, _prefix, MAXPATHLEN); joinpath(prefix, lib_python); } else reduce(prefix); wcsncpy(zip_path, prefix, MAXPATHLEN); zip_path[MAXPATHLEN] = L'\0'; if (pfound > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */ reduce(zip_path); reduce(zip_path); } else wcsncpy(zip_path, _prefix, MAXPATHLEN); joinpath(zip_path, L"lib/python00.zip"); bufsz = wcslen(zip_path); /* Replace "00" with version */ zip_path[bufsz - 6] = VERSION[0]; zip_path[bufsz - 5] = VERSION[2]; if (!(efound = search_for_exec_prefix(argv0_path, home, _exec_prefix))) { if (!Py_FrozenFlag) fprintf(stderr, "Could not find platform dependent libraries <exec_prefix>\n"); wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN); joinpath(exec_prefix, L"lib/lib-dynload"); } /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ if ((!pfound || !efound) && !Py_FrozenFlag) fprintf(stderr, "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n"); /* Calculate size of return buffer. */ bufsz = 0; if (_rtpypath) { size_t s = mbstowcs(rtpypath, _rtpypath, sizeof(rtpypath)/sizeof(wchar_t)); if (s == (size_t)-1 || s >=sizeof(rtpypath)) /* XXX deal with errors more gracefully */ _rtpypath = NULL; if (_rtpypath) bufsz += wcslen(rtpypath) + 1; } defpath = _pythonpath; prefixsz = wcslen(prefix) + 1; while (1) { wchar_t *delim = wcschr(defpath, DELIM); if (defpath[0] != SEP) /* Paths are relative to prefix */ bufsz += prefixsz; if (delim) bufsz += delim - defpath + 1; else { bufsz += wcslen(defpath) + 1; break; } defpath = delim + 1; } bufsz += wcslen(zip_path) + 1; bufsz += wcslen(exec_prefix) + 1; /* This is the only malloc call in this file */ buf = (wchar_t *)PyMem_Malloc(bufsz*sizeof(wchar_t)); if (buf == NULL) { /* We can't exit, so print a warning and limp along */ fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n"); fprintf(stderr, "Using default static PYTHONPATH.\n"); module_search_path = L"" PYTHONPATH; } else { /* Run-time value of $PYTHONPATH goes first */ if (_rtpypath) { wcscpy(buf, rtpypath); wcscat(buf, delimiter); } else buf[0] = '\0'; /* Next is the default zip path */ wcscat(buf, zip_path); wcscat(buf, delimiter); /* Next goes merge of compile-time $PYTHONPATH with * dynamically located prefix. */ defpath = _pythonpath; while (1) { wchar_t *delim = wcschr(defpath, DELIM); if (defpath[0] != SEP) { wcscat(buf, prefix); wcscat(buf, separator); } if (delim) { size_t len = delim - defpath + 1; size_t end = wcslen(buf) + len; wcsncat(buf, defpath, len); *(buf + end) = '\0'; } else { wcscat(buf, defpath); break; } defpath = delim + 1; } wcscat(buf, delimiter); /* Finally, on goes the directory for dynamic-load modules */ wcscat(buf, exec_prefix); /* And publish the results */ module_search_path = buf; } /* Reduce prefix and exec_prefix to their essence, * e.g. /usr/local/lib/python1.5 is reduced to /usr/local. * If we're loading relative to the build directory, * return the compiled-in defaults instead. */ if (pfound > 0) { reduce(prefix); reduce(prefix); /* The prefix is the root directory, but reduce() chopped * off the "/". */ if (!prefix[0]) wcscpy(prefix, separator); } else wcsncpy(prefix, _prefix, MAXPATHLEN); if (efound > 0) { reduce(exec_prefix); reduce(exec_prefix); reduce(exec_prefix); if (!exec_prefix[0]) wcscpy(exec_prefix, separator); } else wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN); PyMem_Free(_pythonpath); PyMem_Free(_prefix); PyMem_Free(_exec_prefix); }
/* * get_newsrcname() * get name of newsrc file with given name of nntp server * returns TRUE if name was found, FALSE if the search failed */ int get_newsrcname( char *newsrc_name, const char *nntpserver_name) /* return value is always ignored */ { FILE *fp; char *line_entry; char line[LEN]; char name_found[PATH_LEN]; int line_entry_counter; int found = 0; t_bool do_cpy = FALSE; if ((fp = fopen(local_newsrctable_file, "r")) != NULL) { while ((fgets(line, (int) sizeof(line), fp) != NULL) && (found != 1)) { line_entry_counter = 0; if (!strchr("# ;", line[0])) { while ((line_entry = strtok(line_entry_counter ? NULL : line, " \t\n")) != NULL) { line_entry_counter++; if ((line_entry_counter == 1) && (!strcasecmp(line_entry, nntpserver_name))) { found = 1; do_cpy = TRUE; } if ((line_entry_counter == 1) && ((!strcasecmp(line_entry, "default")) || (!strcmp(line_entry, "*")))) { found = 2; do_cpy = TRUE; } if (do_cpy && (line_entry_counter == 2)) { strcpy(name_found, line_entry); do_cpy = FALSE; } } } } fclose(fp); if (found) { char dir[PATH_LEN]; char tmp_newsrc[PATH_LEN]; int error = 0; if (!strfpath(name_found, tmp_newsrc, sizeof(tmp_newsrc), NULL)) { my_fprintf(stderr, _("couldn't expand %s\n"), name_found); error = 1; } else { if (tmp_newsrc[0] == '/') (void) strcpy(newsrc_name, tmp_newsrc); else joinpath(newsrc_name, homedir, tmp_newsrc); } (void) strcpy(dir, newsrc_name); if (strchr(dir, '/')) *strrchr(dir, '/') = (char) 0; if (!error) { /* FIXME - write a global permssion check routine */ if (access(dir, X_OK)) { my_fprintf(stderr, _(txt_error_no_enter_permission), dir); error = 1; } else if (access(newsrc_name, F_OK)) { my_fprintf(stderr, _(txt_error_no_such_file), newsrc_name); error = 2; } else if (access(dir, R_OK)) { my_fprintf(stderr, _(txt_error_no_read_permission), dir); error = 1; } else if (access(newsrc_name, R_OK)) { my_fprintf(stderr, _(txt_error_no_read_permission), newsrc_name); error = 1; } else if (access(dir, W_OK)) { my_fprintf(stderr, _(txt_error_no_write_permission), dir); error = 1; } else if (access(newsrc_name, W_OK)) { my_fprintf(stderr, _(txt_error_no_write_permission), newsrc_name); error = 1; } } if (error) { char ch; char default_ch = map_to_local(iKeyNrctblAlternative, &menukeymap.nrctbl_create); do { /* very ugly code, but curses is not initialized yet */ if (error >= 2) { default_ch = map_to_local(iKeyNrctblCreate, &menukeymap.nrctbl_create); printf("%s%c\b", _(txt_nrctbl_create), default_ch); } else printf("%s%c\b", _(txt_nrctbl_default), default_ch); if ((ch = (char) ReadCh()) == '\r' || ch == '\n') ch = default_ch; } while (!strchr(menukeymap.nrctbl_create.localkeys, ch)); printf("%c\n", ch); switch (map_to_default(ch, &menukeymap.nrctbl_create)) { case iKeyNrctblCreate: /* FIXME this doesn't check if we could create the file */ return TRUE; case iKeyNrctblDefault: joinpath(newsrc_name, homedir, ".newsrc"); return TRUE; case iKeyNrctblAlternative: sprintf(name_found, ".newsrc-%s", nntpserver_name); joinpath(newsrc_name, homedir, name_found); return TRUE; case iKeyNrctblQuit: exit(EXIT_SUCCESS); /* keep lint quiet: */ /* FALLTHROUGH */ case ESC: default: return TRUE; } } return TRUE; } } else write_newsrctable_file(); return FALSE; }
static void calculate_path(void) { extern char *Py_GetProgramName(void); static char delimiter[2] = {DELIM, '\0'}; static char separator[2] = {SEP, '\0'}; char *pythonpath = PYTHONPATH; char *rtpypath = getenv("PYTHONPATH"); char *home = Py_GetPythonHome(); char *path = getenv("PATH"); char *prog = Py_GetProgramName(); char argv0_path[MAXPATHLEN+1]; int pfound, efound; /* 1 if found; -1 if found build directory */ char *buf; size_t bufsz; size_t prefixsz; char *defpath = pythonpath; #ifdef WITH_NEXT_FRAMEWORK NSModule pythonModule; #endif #ifdef WITH_NEXT_FRAMEWORK /* XXX Need to check this code for buffer overflows */ pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize")); /* Use dylib functions to find out where the framework was loaded from */ buf = NSLibraryNameForModule(pythonModule); if (buf != NULL) { /* We're in a framework. */ strcpy(progpath, buf); /* Frameworks have support for versioning */ strcpy(lib_python, "lib"); } else { /* If we're not in a framework, fall back to the old way (even though NSNameOfModule() probably does the same thing.) */ #endif /* If there is no slash in the argv0 path, then we have to * assume python is on the user's $PATH, since there's no * other way to find a directory to start the search from. If * $PATH isn't exported, you lose. */ if (strchr(prog, SEP)) strncpy(progpath, prog, MAXPATHLEN); else if (path) { int bufspace = MAXPATHLEN; while (1) { char *delim = strchr(path, DELIM); if (delim) { size_t len = delim - path; if (len > bufspace) len = bufspace; strncpy(progpath, path, len); *(progpath + len) = '\0'; bufspace -= len; } else strncpy(progpath, path, bufspace); joinpath(progpath, prog); if (isxfile(progpath)) break; if (!delim) { progpath[0] = '\0'; break; } path = delim + 1; } } else progpath[0] = '\0'; #ifdef WITH_NEXT_FRAMEWORK } #endif strncpy(argv0_path, progpath, MAXPATHLEN); #if HAVE_READLINK { char tmpbuffer[MAXPATHLEN+1]; int linklen = readlink(progpath, tmpbuffer, MAXPATHLEN); while (linklen != -1) { /* It's not null terminated! */ tmpbuffer[linklen] = '\0'; if (tmpbuffer[0] == SEP) /* tmpbuffer should never be longer than MAXPATHLEN, but extra check does not hurt */ strncpy(argv0_path, tmpbuffer, MAXPATHLEN); else { /* Interpret relative to progpath */ reduce(argv0_path); joinpath(argv0_path, tmpbuffer); } linklen = readlink(argv0_path, tmpbuffer, MAXPATHLEN); } } #endif /* HAVE_READLINK */ reduce(argv0_path); /* At this point, argv0_path is guaranteed to be less than MAXPATHLEN bytes long. */ if (!(pfound = search_for_prefix(argv0_path, home))) { if (!Py_FrozenFlag) fprintf(stderr, "Could not find platform independent libraries <prefix>\n"); strncpy(prefix, PREFIX, MAXPATHLEN); joinpath(prefix, lib_python); } else reduce(prefix); if (!(efound = search_for_exec_prefix(argv0_path, home))) { if (!Py_FrozenFlag) fprintf(stderr, "Could not find platform dependent libraries <exec_prefix>\n"); strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN); joinpath(exec_prefix, "lib/lib-dynload"); } /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ if ((!pfound || !efound) && !Py_FrozenFlag) fprintf(stderr, "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n"); /* Calculate size of return buffer. */ bufsz = 0; if (rtpypath) bufsz += strlen(rtpypath) + 1; prefixsz = strlen(prefix) + 1; while (1) { char *delim = strchr(defpath, DELIM); if (defpath[0] != SEP) /* Paths are relative to prefix */ bufsz += prefixsz; if (delim) bufsz += delim - defpath + 1; else { bufsz += strlen(defpath) + 1; break; } defpath = delim + 1; } bufsz += strlen(exec_prefix) + 1; /* This is the only malloc call in this file */ buf = PyMem_Malloc(bufsz); if (buf == NULL) { /* We can't exit, so print a warning and limp along */ fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n"); fprintf(stderr, "Using default static PYTHONPATH.\n"); module_search_path = PYTHONPATH; } else { /* Run-time value of $PYTHONPATH goes first */ if (rtpypath) { strcpy(buf, rtpypath); strcat(buf, delimiter); } else buf[0] = '\0'; /* Next goes merge of compile-time $PYTHONPATH with * dynamically located prefix. */ defpath = pythonpath; while (1) { char *delim = strchr(defpath, DELIM); if (defpath[0] != SEP) { strcat(buf, prefix); strcat(buf, separator); } if (delim) { size_t len = delim - defpath + 1; size_t end = strlen(buf) + len; strncat(buf, defpath, len); *(buf + end) = '\0'; } else { strcat(buf, defpath); break; } defpath = delim + 1; } strcat(buf, delimiter); /* Finally, on goes the directory for dynamic-load modules */ strcat(buf, exec_prefix); /* And publish the results */ module_search_path = buf; } /* Reduce prefix and exec_prefix to their essence, * e.g. /usr/local/lib/python1.5 is reduced to /usr/local. * If we're loading relative to the build directory, * return the compiled-in defaults instead. */ if (pfound > 0) { reduce(prefix); reduce(prefix); } else strncpy(prefix, PREFIX, MAXPATHLEN); if (efound > 0) { reduce(exec_prefix); reduce(exec_prefix); reduce(exec_prefix); } else strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN); }
/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN bytes long. */ static int search_for_prefix(char *argv0_path, char *home) { size_t n; char *vpath; /* If PYTHONHOME is set, we believe it unconditionally */ if (home) { char *delim; strncpy(prefix, home, MAXPATHLEN); delim = strchr(prefix, DELIM); if (delim) *delim = '\0'; joinpath(prefix, lib_python); joinpath(prefix, LANDMARK); return 1; } /* Check to see if argv[0] is in the build directory */ strcpy(prefix, argv0_path); joinpath(prefix, "Modules/Setup"); if (isfile(prefix)) { /* Check VPATH to see if argv0_path is in the build directory. * Complication: the VPATH passed in is relative to the * Modules build directory and points to the Modules source * directory; we need it relative to the build tree and * pointing to the source tree. Solution: chop off a leading * ".." (but only if it's there -- it could be an absolute * path) and chop off the final component (assuming it's * "Modules"). */ vpath = VPATH; if (vpath[0] == '.' && vpath[1] == '.' && vpath[2] == '/') vpath += 3; strcpy(prefix, argv0_path); joinpath(prefix, vpath); reduce(prefix); joinpath(prefix, "Lib"); joinpath(prefix, LANDMARK); if (ismodule(prefix)) return -1; } /* Search from argv0_path, until root is found */ init_path_from_argv0(prefix, argv0_path); do { n = strlen(prefix); joinpath(prefix, lib_python); joinpath(prefix, LANDMARK); if (ismodule(prefix)) return 1; prefix[n] = '\0'; reduce(prefix); } while (prefix[0]); /* Look at configure's PREFIX */ strncpy(prefix, PREFIX, MAXPATHLEN); joinpath(prefix, lib_python); joinpath(prefix, LANDMARK); if (ismodule(prefix)) return 1; /* Fail */ return 0; }
int main(int argc, char ** argv) { FILE *containerimage_fp; FILE *loop_fp; FILE *config_fp; char *containerimage; char *containername; char *containerpath; char *username; char *command; char *tmpdir; char *loop_dev_lock; char *loop_dev_cache; char *loop_dev = 0; char *config_path; char *tmp_config_string; char cwd[PATH_MAX]; int cwd_fd; int tmpdirlock_fd; int containerimage_fd; int loop_dev_lock_fd; int gid_list_count; int retval = 0; uid_t uid; gid_t gid; gid_t *gid_list; pid_t namespace_fork_pid = 0; struct passwd *pw; //****************************************************************************// // Init //****************************************************************************// signal(SIGINT, sighandler); signal(SIGKILL, sighandler); signal(SIGQUIT, sighandler); openlog("Singularity", LOG_CONS | LOG_NDELAY, LOG_LOCAL0); // Get all user/group info uid = getuid(); gid = getgid(); gid_list_count = getgroups(0, NULL); gid_list = (gid_t *) malloc(sizeof(gid_t) * gid_list_count); if ( getgroups(gid_list_count, gid_list) < 0 ) { fprintf(stderr, "ABORT: Could not obtain current supplementary group list: %s\n", strerror(errno)); return(255); } pw = getpwuid(uid); // Check to make sure we are installed correctly if ( seteuid(0) < 0 ) { fprintf(stderr, "ABORT: Check installation, must be performed by root.\n"); return(255); } // Lets start off as the calling UID if ( seteuid(uid) < 0 ) { fprintf(stderr, "ABORT: Could not set effective uid to %d: %s\n", uid, strerror(errno)); return(255); } if ( setegid(gid) < 0 ) { fprintf(stderr, "ABORT: Could not set effective gid to %d: %s\n", gid, strerror(errno)); return(255); } username = pw->pw_name; containerimage = getenv("SINGULARITY_IMAGE"); command = getenv("SINGULARITY_COMMAND"); unsetenv("SINGULARITY_COMMAND"); unsetenv("SINGULARITY_EXEC"); config_path = (char *) malloc(strlen(SYSCONFDIR) + 30); snprintf(config_path, strlen(SYSCONFDIR) + 30, "%s/singularity/singularity.conf", SYSCONFDIR); // Figure out where we start if ( (cwd_fd = open(".", O_RDONLY)) < 0 ) { fprintf(stderr, "ABORT: Could not open cwd fd (%s)!\n", strerror(errno)); return(1); } if ( getcwd(cwd, PATH_MAX) == NULL ) { fprintf(stderr, "Could not obtain current directory path: %s\n", strerror(errno)); return(1); } if ( containerimage == NULL ) { fprintf(stderr, "ABORT: SINGULARITY_IMAGE undefined!\n"); return(1); } if ( is_file(containerimage) != 0 ) { fprintf(stderr, "ABORT: Container image path is invalid: %s\n", containerimage); return(1); } if ( is_file(config_path) != 0 ) { fprintf(stderr, "ABORT: Configuration file not found: %s\n", config_path); return(255); } if ( is_owner(config_path, 0) != 0 ) { fprintf(stderr, "ABORT: Configuration file is not owned by root: %s\n", config_path); return(255); } // TODO: Offer option to only run containers owned by root (so root can approve // containers) if ( uid == 0 && is_owner(containerimage, 0) < 0 ) { fprintf(stderr, "ABORT: Root should only run containers that root owns!\n"); return(1); } containername = basename(strdup(containerimage)); tmpdir = strjoin("/tmp/.singularity-", file_id(containerimage)); loop_dev_lock = joinpath(tmpdir, "loop_dev.lock"); loop_dev_cache = joinpath(tmpdir, "loop_dev"); containerpath = (char *) malloc(strlen(tmpdir) + 5); snprintf(containerpath, strlen(tmpdir) + 5, "%s/mnt", tmpdir); syslog(LOG_NOTICE, "User=%s[%d], Command=%s, Container=%s, CWD=%s, Arg1=%s", username, uid, command, containerimage, cwd, argv[1]); //****************************************************************************// // Setup //****************************************************************************// if ( ( config_fp = fopen(config_path, "r") ) == NULL ) { fprintf(stderr, "ERROR: Could not open config file %s: %s\n", config_path, strerror(errno)); return(255); } if ( getenv("SINGULARITY_WRITABLE") == NULL ) { if ( ( containerimage_fp = fopen(containerimage, "r") ) == NULL ) { fprintf(stderr, "ERROR: Could not open image read only %s: %s\n", containerimage, strerror(errno)); return(255); } containerimage_fd = fileno(containerimage_fp); if ( flock(containerimage_fd, LOCK_SH | LOCK_NB) < 0 ) { fprintf(stderr, "ABORT: Image is locked by another process\n"); return(5); } } else { if ( ( containerimage_fp = fopen(containerimage, "r+") ) == NULL ) { fprintf(stderr, "ERROR: Could not open image read/write %s: %s\n", containerimage, strerror(errno)); return(255); } containerimage_fd = fileno(containerimage_fp); if ( flock(containerimage_fd, LOCK_EX | LOCK_NB) < 0 ) { fprintf(stderr, "ABORT: Image is locked by another process\n"); return(5); } } //****************************************************************************// // We are now running with escalated privileges until we exec //****************************************************************************// if ( seteuid(0) < 0 ) { fprintf(stderr, "ABORT: Could not escalate effective user privileges %s\n", strerror(errno)); return(255); } if ( setegid(0) < 0 ) { fprintf(stderr, "ABORT: Could not escalate effective group privileges: %s\n", strerror(errno)); return(255); } if ( s_mkpath(tmpdir, 0755) < 0 ) { fprintf(stderr, "ABORT: Could not create temporary directory %s: %s\n", tmpdir, strerror(errno)); return(255); } if ( is_owner(tmpdir, 0) < 0 ) { fprintf(stderr, "ABORT: Container working directory has wrong ownership: %s\n", tmpdir); syslog(LOG_ERR, "Container working directory has wrong ownership: %s", tmpdir); return(255); } tmpdirlock_fd = open(tmpdir, O_RDONLY); if ( tmpdirlock_fd < 0 ) { fprintf(stderr, "ERROR: Could not obtain file descriptor on %s: %s\n", tmpdir, strerror(errno)); return(255); } if ( flock(tmpdirlock_fd, LOCK_SH | LOCK_NB) < 0 ) { fprintf(stderr, "ERROR: Could not obtain shared lock on %s: %s\n", tmpdir, strerror(errno)); return(255); } if ( ( loop_dev_lock_fd = open(loop_dev_lock, O_CREAT | O_RDWR, 0644) ) < 0 ) { fprintf(stderr, "ERROR: Could not open loop_dev_lock %s: %s\n", loop_dev_lock, strerror(errno)); return(255); } if ( s_mkpath(containerpath, 0755) < 0 ) { fprintf(stderr, "ABORT: Could not create directory %s: %s\n", containerpath, strerror(errno)); return(255); } if ( is_owner(containerpath, 0) < 0 ) { fprintf(stderr, "ABORT: Container directory is not root owned: %s\n", containerpath); syslog(LOG_ERR, "Container directory has wrong ownership: %s", tmpdir); return(255); } if ( flock(loop_dev_lock_fd, LOCK_EX | LOCK_NB) == 0 ) { loop_dev = obtain_loop_dev(); if ( ( loop_fp = fopen(loop_dev, "r+") ) < 0 ) { fprintf(stderr, "ERROR: Failed to open loop device %s: %s\n", loop_dev, strerror(errno)); syslog(LOG_ERR, "Failed to open loop device %s: %s", loop_dev, strerror(errno)); return(255); } if ( associate_loop(containerimage_fp, loop_fp, 1) < 0 ) { fprintf(stderr, "ERROR: Could not associate %s to loop device %s\n", containerimage, loop_dev); syslog(LOG_ERR, "Failed to associate %s to loop device %s", containerimage, loop_dev); return(255); } if ( fileput(loop_dev_cache, loop_dev) < 0 ) { fprintf(stderr, "ERROR: Could not write to loop_dev_cache %s: %s\n", loop_dev_cache, strerror(errno)); return(255); } flock(loop_dev_lock_fd, LOCK_SH | LOCK_NB); } else { flock(loop_dev_lock_fd, LOCK_SH); if ( ( loop_dev = filecat(loop_dev_cache) ) == NULL ) { fprintf(stderr, "ERROR: Could not retrieve loop_dev_cache from %s\n", loop_dev_cache); return(255); } if ( ( loop_fp = fopen(loop_dev, "r") ) < 0 ) { fprintf(stderr, "ERROR: Failed to open loop device %s: %s\n", loop_dev, strerror(errno)); return(255); } } //****************************************************************************// // Management fork //****************************************************************************// namespace_fork_pid = fork(); if ( namespace_fork_pid == 0 ) { //****************************************************************************// // Setup namespaces //****************************************************************************// if ( unshare(CLONE_NEWNS) < 0 ) { fprintf(stderr, "ABORT: Could not virtualize mount namespace: %s\n", strerror(errno)); return(255); } // Privatize the mount namespaces (thank you for the pointer Doug Jacobsen!) if ( mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0 ) { // I am not sure if this error needs to be caught, maybe it will fail // on older kernels? If so, we can fix then. fprintf(stderr, "ABORT: Could not make mountspaces private: %s\n", strerror(errno)); return(255); } #ifdef NS_CLONE_NEWPID if ( getenv("SINGULARITY_NO_NAMESPACE_PID") == NULL ) { unsetenv("SINGULARITY_NO_NAMESPACE_PID"); if ( unshare(CLONE_NEWPID) < 0 ) { fprintf(stderr, "ABORT: Could not virtualize PID namespace: %s\n", strerror(errno)); return(255); } } #else #ifdef NS_CLONE_PID // This is for older legacy CLONE_PID if ( getenv("SINGULARITY_NO_NAMESPACE_PID") == NULL ) { unsetenv("SINGULARITY_NO_NAMESPACE_PID"); if ( unshare(CLONE_PID) < 0 ) { fprintf(stderr, "ABORT: Could not virtualize PID namespace: %s\n", strerror(errno)); return(255); } } #endif #endif #ifdef NS_CLONE_FS if ( getenv("SINGULARITY_NO_NAMESPACE_FS") == NULL ) { unsetenv("SINGULARITY_NO_NAMESPACE_FS"); if ( unshare(CLONE_FS) < 0 ) { fprintf(stderr, "ABORT: Could not virtualize file system namespace: %s\n", strerror(errno)); return(255); } } #endif #ifdef NS_CLONE_FILES if ( getenv("SINGULARITY_NO_NAMESPACE_FILES") == NULL ) { unsetenv("SINGULARITY_NO_NAMESPACE_FILES"); if ( unshare(CLONE_FILES) < 0 ) { fprintf(stderr, "ABORT: Could not virtualize file descriptor namespace: %s\n", strerror(errno)); return(255); } } #endif //****************************************************************************// // Mount image //****************************************************************************// if ( getenv("SINGULARITY_WRITABLE") == NULL ) { unsetenv("SINGULARITY_WRITABLE"); if ( mount_image(loop_dev, containerpath, 0) < 0 ) { fprintf(stderr, "ABORT: exiting...\n"); return(255); } } else { if ( mount_image(loop_dev, containerpath, 1) < 0 ) { fprintf(stderr, "ABORT: exiting...\n"); return(255); } } //****************************************************************************// // Check image //****************************************************************************// if ( is_exec(joinpath(containerpath, "/bin/sh")) < 0 ) { fprintf(stderr, "ERROR: Container image does not have a valid /bin/sh\n"); return(1); } //****************************************************************************// // Bind mounts //****************************************************************************// if ( getenv("SINGULARITY_CONTAIN") == NULL ) { unsetenv("SINGULARITY_CONTAIN"); rewind(config_fp); while ( ( tmp_config_string = config_get_key_value(config_fp, "bind path") ) != NULL ) { if ( ( is_file(tmp_config_string) != 0 ) && ( is_dir(tmp_config_string) != 0 ) ) { fprintf(stderr, "ERROR: Non existant bind source path: '%s'\n", tmp_config_string); continue; } if ( ( is_file(joinpath(containerpath, tmp_config_string)) != 0 ) && ( is_dir(joinpath(containerpath, tmp_config_string)) != 0 ) ) { fprintf(stderr, "WARNING: Non existant bind container destination path: '%s'\n", tmp_config_string); continue; } if ( mount_bind(tmp_config_string, joinpath(containerpath, tmp_config_string), 0) < 0 ) { fprintf(stderr, "ABORTING!\n"); return(255); } } if (is_file(joinpath(containerpath, "/etc/nsswitch.conf")) == 0 ) { if ( is_file(joinpath(SYSCONFDIR, "/singularity/default-nsswitch.conf")) == 0 ) { if ( mount_bind(joinpath(SYSCONFDIR, "/singularity/default-nsswitch.conf"), joinpath(containerpath, "/etc/nsswitch.conf"), 0) != 0 ) { fprintf(stderr, "ABORT: Could not bind /etc/nsswitch.conf\n"); return(255); } } else { fprintf(stderr, "WARNING: Template /etc/nsswitch.conf does not exist: %s\n", joinpath(SYSCONFDIR, "/singularity/default-nsswitch.conf")); } } if ( uid != 0 ) { // If we are root, no need to mess with passwd or group if (is_file(joinpath(containerpath, "/etc/passwd")) == 0 ) { if ( is_file(joinpath(tmpdir, "/passwd")) < 0 ) { if ( build_passwd(joinpath(containerpath, "/etc/passwd"), joinpath(tmpdir, "/passwd")) < 0 ) { fprintf(stderr, "ABORT: Failed creating template password file\n"); return(255); } } if ( mount_bind(joinpath(tmpdir, "/passwd"), joinpath(containerpath, "/etc/passwd"), 0) < 0 ) { fprintf(stderr, "ABORT: Could not bind /etc/passwd\n"); return(255); } } if (is_file(joinpath(containerpath, "/etc/group")) == 0 ) { if ( is_file(joinpath(tmpdir, "/group")) < 0 ) { if ( build_group(joinpath(containerpath, "/etc/group"), joinpath(tmpdir, "/group")) < 0 ) { fprintf(stderr, "ABORT: Failed creating template group file\n"); return(255); } } if ( mount_bind(joinpath(tmpdir, "/group"), joinpath(containerpath, "/etc/group"), 0) < 0 ) { fprintf(stderr, "ABORT: Could not bind /etc/group\n"); return(255); } } } } //****************************************************************************// // Fork child in new namespaces //****************************************************************************// exec_fork_pid = fork(); if ( exec_fork_pid == 0 ) { //****************************************************************************// // Enter the file system //****************************************************************************// if ( chroot(containerpath) < 0 ) { fprintf(stderr, "ABORT: failed enter CONTAINERIMAGE: %s\n", containerpath); return(255); } if ( chdir("/") < 0 ) { fprintf(stderr, "ABORT: Could not chdir after chroot to /: %s\n", strerror(errno)); return(1); } //****************************************************************************// // Setup real mounts within the container //****************************************************************************// rewind(config_fp); if ( config_get_key_bool(config_fp, "mount proc", 1) > 0 ) { if ( is_dir("/proc") == 0 ) { if ( mount("proc", "/proc", "proc", 0, NULL) < 0 ) { fprintf(stderr, "ABORT: Could not mount /proc: %s\n", strerror(errno)); return(255); } } } rewind(config_fp); if ( config_get_key_bool(config_fp, "mount sys", 1) > 0 ) { if ( is_dir("/sys") == 0 ) { if ( mount("sysfs", "/sys", "sysfs", 0, NULL) < 0 ) { fprintf(stderr, "ABORT: Could not mount /sys: %s\n", strerror(errno)); return(255); } } } //****************************************************************************// // Drop all privileges for good //****************************************************************************// if ( setgroups(gid_list_count, gid_list) < 0 ) { fprintf(stderr, "ABOFT: Could not reset supplementary group list: %s\n", strerror(errno)); return(255); } if ( setregid(gid, gid) < 0 ) { fprintf(stderr, "ABORT: Could not dump real and effective group privileges: %s\n", strerror(errno)); return(255); } if ( setreuid(uid, uid) < 0 ) { fprintf(stderr, "ABORT: Could not dump real and effective user privileges: %s\n", strerror(errno)); return(255); } //****************************************************************************// // Setup final environment //****************************************************************************// // After this, we exist only within the container... Let's make it known! if ( setenv("SINGULARITY_CONTAINER", "true", 0) != 0 ) { fprintf(stderr, "ABORT: Could not set SINGULARITY_CONTAINER to 'true'\n"); return(1); } if ( is_dir(cwd) == 0 ) { if ( chdir(cwd) < 0 ) { fprintf(stderr, "ABORT: Could not chdir to: %s: %s\n", cwd, strerror(errno)); return(1); } } else { if ( fchdir(cwd_fd) < 0 ) { fprintf(stderr, "ABORT: Could not fchdir to cwd: %s\n", strerror(errno)); return(1); } } //****************************************************************************// // Execv to container process //****************************************************************************// if ( command == NULL ) { fprintf(stderr, "No command specified, launching 'shell'\n"); command = strdup("shell"); } if ( strcmp(command, "run") == 0 ) { if ( is_exec("/singularity") == 0 ) { argv[0] = strdup("/singularity"); if ( execv("/singularity", argv) != 0 ) { fprintf(stderr, "ABORT: exec of /bin/sh failed: %s\n", strerror(errno)); } } else { fprintf(stderr, "No Singularity runscript found, launching 'shell'\n"); command = strdup("shell"); } } if ( strcmp(command, "exec") == 0 ) { if ( argc <= 1 ) { fprintf(stderr, "ABORT: Exec requires a command to run\n"); return(1); } if ( execvp(argv[1], &argv[1]) != 0 ) { fprintf(stderr, "ABORT: execvp of '%s' failed: %s\n", argv[1], strerror(errno)); return(1); } } if ( strcmp(command, "shell") == 0 ) { char *prompt; prompt = (char *) malloc(strlen(containername) + 16); snprintf(prompt, strlen(containerimage) + 16, "Singularity/%s> ", containername); setenv("PS1", prompt, 1); if ( is_exec("/bin/bash") == 0 ) { char *args[argc+2]; int i; args[0] = strdup("/bin/bash"); args[1] = strdup("--norc"); args[2] = strdup("--noprofile"); for(i=1; i<=argc; i++) { args[i+2] = argv[i]; } if ( execv("/bin/bash", args) != 0 ) { fprintf(stderr, "ABORT: exec of /bin/bash failed: %s\n", strerror(errno)); } } else { argv[0] = strdup("/bin/sh"); if ( execv("/bin/sh", argv) != 0 ) { fprintf(stderr, "ABORT: exec of /bin/sh failed: %s\n", strerror(errno)); } } } // If we get here... we fail on bad command fprintf(stderr, "ABORT: Unrecognized Singularity command: %s\n", command); return(1); //****************************************************************************// // Outer child waits for inner child //****************************************************************************// } else if ( exec_fork_pid > 0 ) { int tmpstatus; strncpy(argv[0], "Singularity: exec", strlen(argv[0])); if ( seteuid(uid) < 0 ) { fprintf(stderr, "ABORT: Could not set effective user privileges to %d: %s\n", uid, strerror(errno)); return(255); } waitpid(exec_fork_pid, &tmpstatus, 0); retval = WEXITSTATUS(tmpstatus); } else { fprintf(stderr, "ABORT: Could not fork namespace process: %s\n", strerror(errno)); return(255); } return(retval); } else if ( namespace_fork_pid > 0 ) { int tmpstatus; strncpy(argv[0], "Singularity: namespace", strlen(argv[0])); if ( seteuid(uid) < 0 ) { fprintf(stderr, "ABORT: Could not set effective user privileges to %d: %s\n", uid, strerror(errno)); return(255); } waitpid(namespace_fork_pid, &tmpstatus, 0); retval = WEXITSTATUS(tmpstatus); } else { fprintf(stderr, "ABORT: Could not fork management process: %s\n", strerror(errno)); return(255); } //****************************************************************************// // Final wrap up before exiting //****************************************************************************// if ( close(cwd_fd) < 0 ) { fprintf(stderr, "ERROR: Could not close cwd_fd: %s\n", strerror(errno)); retval++; } if ( flock(tmpdirlock_fd, LOCK_EX | LOCK_NB) == 0 ) { close(tmpdirlock_fd); if ( seteuid(0) < 0 ) { fprintf(stderr, "ABORT: Could not re-escalate effective user privileges: %s\n", strerror(errno)); return(255); } if ( s_rmdir(tmpdir) < 0 ) { fprintf(stderr, "WARNING: Could not remove all files in %s: %s\n", tmpdir, strerror(errno)); } // Dissociate loops from here Just in case autoflush didn't work. (void)disassociate_loop(loop_fp); if ( seteuid(uid) < 0 ) { fprintf(stderr, "ABORT: Could not drop effective user privileges: %s\n", strerror(errno)); return(255); } } else { // printf("Not removing tmpdir, lock still\n"); } close(containerimage_fd); close(tmpdirlock_fd); free(loop_dev_lock); free(containerpath); free(tmpdir); closelog(); return(retval); }
/* * Read the ${TIN_HOMEDIR:-"$HOME"}/.newsauth file and put authentication * username and password for the specified server in the given strings. * Returns TRUE if at least a password was found, FALSE if there was * no .newsauth file or no matching server. */ static t_bool read_newsauth_file( char *server, char *authuser, char *authpass) { FILE *fp; char *_authpass; char *ptr; char filename[PATH_LEN]; char line[PATH_LEN]; int found = 0; int fd; struct stat statbuf; joinpath(filename, sizeof(filename), homedir, ".newsauth"); if ((fp = fopen(filename, "r"))) { if ((fd = fileno(fp)) == -1) { fclose(fp); return FALSE; } if (fstat(fd, &statbuf) == -1) { fclose(fp); return FALSE; } # ifndef FILE_MODE_BROKEN if (S_ISREG(statbuf.st_mode) && (statbuf.st_mode|S_IRUSR|S_IWUSR) != (S_IRUSR|S_IWUSR|S_IFREG)) { error_message(4, _(txt_error_insecure_permissions), filename, statbuf.st_mode); /* * TODO: fix permssions? * fchmod(fd, S_IRUSR|S_IWUSR); */ } # endif /* !FILE_MODE_BROKEN */ /* * Search through authorization file for correct NNTP server * File has format: 'nntp-server' 'password' ['username'] */ while (fgets(line, sizeof(line), fp) != NULL) { /* strip trailing newline character */ ptr = strchr(line, '\n'); if (ptr != NULL) *ptr = '\0'; /* Get server from 1st part of the line */ ptr = strpbrk(line, " \t"); if (ptr == NULL) /* no passwd, no auth, skip */ continue; *ptr++ = '\0'; /* cut off server part */ if ((strcasecmp(line, server))) continue; /* wrong server, keep on */ /* Get password from 2nd part of the line */ while (*ptr == ' ' || *ptr == '\t') ptr++; /* skip any blanks */ _authpass = ptr; if (*_authpass == '"') { /* skip "embedded" password string */ ptr = strrchr(_authpass, '"'); if ((ptr != NULL) && (ptr > _authpass)) { _authpass++; *ptr++ = '\0'; /* cut off trailing " */ } else /* no matching ", proceede as normal */ ptr = _authpass; } /* Get user from 3rd part of the line */ ptr = strpbrk(ptr, " \t"); /* find next separating blank */ if (ptr != NULL) { /* a 3rd argument follows */ while (*ptr == ' ' || *ptr == '\t') /* skip any blanks */ *ptr++ = '\0'; if (*ptr != '\0') /* if its not just empty */ strcpy(authuser, ptr); /* so will replace default user */ } strcpy(authpass, _authpass); found++; break; /* if we end up here, everything seems OK */ } fclose(fp); return (found > 0); } return FALSE; }
/* search_for_exec_prefix requires that argv0_path be no more than MAXPATHLEN bytes long. */ static int search_for_exec_prefix(char *argv0_path, char *home) { size_t n; /* If PYTHONHOME is set, we believe it unconditionally */ if (home) { char *delim; delim = strchr(home, DELIM); if (delim) strncpy(exec_prefix, delim+1, MAXPATHLEN); else strncpy(exec_prefix, home, MAXPATHLEN); joinpath(exec_prefix, lib_python); joinpath(exec_prefix, "lib-dynload"); return 1; } /* Check to see if argv[0] is in the build directory. "pybuilddir.txt" is written by setup.py and contains the relative path to the location of shared library modules. */ strcpy(exec_prefix, argv0_path); joinpath(exec_prefix, "pybuilddir.txt"); if (isfile(exec_prefix)) { FILE *f = fopen(exec_prefix, "r"); if (f == NULL) errno = 0; else { char rel_builddir_path[MAXPATHLEN+1]; size_t n; n = fread(rel_builddir_path, 1, MAXPATHLEN, f); rel_builddir_path[n] = '\0'; fclose(f); if (n >= 0) { strcpy(exec_prefix, argv0_path); joinpath(exec_prefix, rel_builddir_path); return -1; } } } /* Search from argv0_path, until root is found */ copy_absolute(exec_prefix, argv0_path); do { n = strlen(exec_prefix); joinpath(exec_prefix, lib_python); joinpath(exec_prefix, "lib-dynload"); if (isdir(exec_prefix)) return 1; exec_prefix[n] = '\0'; reduce(exec_prefix); } while (exec_prefix[0]); /* Look at configure's EXEC_PREFIX */ strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN); joinpath(exec_prefix, lib_python); joinpath(exec_prefix, "lib-dynload"); if (isdir(exec_prefix)) return 1; /* Fail */ 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); }
/* search_for_exec_prefix requires that argv0_path be no more than MAXPATHLEN bytes long. */ static int search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_exec_prefix) { size_t n; /* If PYTHONHOME is set, we believe it unconditionally */ if (home) { wchar_t *delim; delim = wcschr(home, DELIM); if (delim) wcsncpy(exec_prefix, delim+1, MAXPATHLEN); else wcsncpy(exec_prefix, home, MAXPATHLEN); joinpath(exec_prefix, lib_python); joinpath(exec_prefix, L"lib-dynload"); return 1; } /* Check to see if argv[0] is in the build directory. "pybuilddir.txt" is written by setup.py and contains the relative path to the location of shared library modules. */ wcscpy(exec_prefix, argv0_path); joinpath(exec_prefix, L"pybuilddir.txt"); if (isfile(exec_prefix)) { FILE *f = _Py_wfopen(exec_prefix, L"rb"); if (f == NULL) errno = 0; else { char buf[MAXPATHLEN+1]; PyObject *decoded; wchar_t rel_builddir_path[MAXPATHLEN+1]; n = fread(buf, 1, MAXPATHLEN, f); buf[n] = '\0'; fclose(f); decoded = PyUnicode_DecodeUTF8(buf, n, "surrogateescape"); if (decoded != NULL) { Py_ssize_t k; k = PyUnicode_AsWideChar(decoded, rel_builddir_path, MAXPATHLEN); Py_DECREF(decoded); if (k >= 0) { rel_builddir_path[k] = L'\0'; wcscpy(exec_prefix, argv0_path); joinpath(exec_prefix, rel_builddir_path); return -1; } } } } /* Search from argv0_path, until root is found */ copy_absolute(exec_prefix, argv0_path, MAXPATHLEN+1); do { n = wcslen(exec_prefix); joinpath(exec_prefix, lib_python); joinpath(exec_prefix, L"lib-dynload"); if (isdir(exec_prefix)) return 1; exec_prefix[n] = L'\0'; reduce(exec_prefix); } while (exec_prefix[0]); /* Look at configure's EXEC_PREFIX */ wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN); joinpath(exec_prefix, lib_python); joinpath(exec_prefix, L"lib-dynload"); if (isdir(exec_prefix)) return 1; /* Fail */ return 0; }
int _singularity_runtime_files_passwd(void) { FILE *file_fp; char *source_file; char *tmp_file; char *homedir = singularity_priv_home(); uid_t uid = singularity_priv_getuid(); struct passwd *pwent = getpwuid(uid); char *containerdir = CONTAINER_FINALDIR; char *tmpdir = singularity_registry_get("SESSIONDIR"); singularity_message(DEBUG, "Called singularity_file_passwd_create()\n"); if ( uid == 0 ) { singularity_message(VERBOSE, "Not updating passwd file, running as root!\n"); return(0); } if ( containerdir == NULL ) { singularity_message(ERROR, "Failed to obtain container directory\n"); ABORT(255); } if ( tmpdir == NULL ) { singularity_message(ERROR, "Failed to obtain session directory\n"); ABORT(255); } singularity_message(DEBUG, "Checking configuration option: 'config passwd'\n"); if ( singularity_config_get_bool(CONFIG_PASSWD) <= 0 ) { singularity_message(VERBOSE, "Skipping bind of the host's /etc/passwd\n"); return(0); } source_file = joinpath(containerdir, "/etc/passwd"); tmp_file = joinpath(tmpdir, "/passwd"); singularity_message(VERBOSE2, "Checking for template passwd file: %s\n", source_file); if ( is_file(source_file) < 0 ) { singularity_message(VERBOSE, "Passwd file does not exist in container, not updating\n"); return(0); } singularity_message(VERBOSE2, "Creating template of /etc/passwd\n"); if ( ( copy_file(source_file, tmp_file) ) < 0 ) { singularity_message(ERROR, "Failed copying template passwd file to tmpdir: %s\n", strerror(errno)); ABORT(255); } singularity_message(VERBOSE, "Creating template passwd file and appending user data: %s\n", tmp_file); if ( ( file_fp = fopen(tmp_file, "a") ) == NULL ) { // Flawfinder: ignore singularity_message(ERROR, "Could not open template passwd file %s: %s\n", tmp_file, strerror(errno)); ABORT(255); } fprintf(file_fp, "%s:x:%d:%d:%s:%s:%s\n", pwent->pw_name, pwent->pw_uid, pwent->pw_gid, pwent->pw_gecos, homedir, pwent->pw_shell); fclose(file_fp); container_file_bind(tmp_file, "/etc/passwd"); // set HOME to the homedir, because it might be different than outside envar_set("HOME", homedir, 1); return(0); }
/** Determine paths. Two directories must be found, the platform independent directory (prefix), containing the common .py and .pyc files, and the platform dependent directory (exec_prefix), containing the shared library modules. Note that prefix and exec_prefix are the same directory for UEFI installations. Separate searches are carried out for prefix and exec_prefix. Each search tries a number of different locations until a ``landmark'' file or directory is found. If no prefix or exec_prefix is found, a warning message is issued and the preprocessor defined PREFIX and EXEC_PREFIX are used (even though they may not work); python carries on as best as is possible, but some imports may fail. Before any searches are done, the location of the executable is determined. If argv[0] has one or more slashes in it, it is used unchanged. Otherwise, it must have been invoked from the shell's path, so we search %PATH% for the named executable and use that. If the executable was not found on %PATH% (or there was no %PATH% environment variable), the original argv[0] string is used. Finally, argv0_path is set to the directory containing the executable (i.e. the last component is stripped). With argv0_path in hand, we perform a number of steps. The same steps are performed for prefix and for exec_prefix, but with a different landmark. The prefix landmark will always be lib/python.VERSION/os.py and the exec_prefix will always be lib/python.VERSION/dynaload, where VERSION is Python's version number as defined at the beginning of this file. First. See if the %PYTHONHOME% environment variable points to the installed location of the Python libraries. If %PYTHONHOME% is set, then it points to prefix and exec_prefix. %PYTHONHOME% can be a single directory, which is used for both, or the prefix and exec_prefix directories separated by the DELIM character. Next. Search the directories pointed to by the preprocessor variables PREFIX and EXEC_PREFIX. These paths are prefixed with the volume name extracted from argv0_path. The volume names correspond to the UEFI shell "map" names. That's it! Well, almost. Once we have determined prefix and exec_prefix, the preprocessor variable PYTHONPATH is used to construct a path. Each relative path on PYTHONPATH is prefixed with prefix. Then the directory containing the shared library modules is appended. The environment variable $PYTHONPATH is inserted in front of it all. Finally, the prefix and exec_prefix globals are tweaked so they reflect the values expected by other code, by stripping the "lib/python$VERSION/..." stuff off. This seems to make more sense given that currently the only known use of sys.prefix and sys.exec_prefix is for the ILU installation process to find the installed Python tree. The final, fully resolved, paths should look something like: fs0:/Efi/Tools/python.efi fs0:/Efi/StdLib/lib/python27 fs0:/Efi/StdLib/lib/python27/dynaload **/ static void calculate_path(void) { extern char *Py_GetProgramName(void); static char delimiter[2] = {DELIM, '\0'}; static char separator[2] = {SEP, '\0'}; char *pythonpath = PYTHONPATH; char *rtpypath = Py_GETENV("PYTHONPATH"); //char *home = Py_GetPythonHome(); char *path = getenv("path"); char *prog = Py_GetProgramName(); char argv0_path[MAXPATHLEN+1]; char zip_path[MAXPATHLEN+1]; char *buf; size_t bufsz; size_t prefixsz; char *defpath; /* ########################################################################### Determine path to the Python.efi binary. Produces progpath, argv0_path, and volume_name. ########################################################################### */ /* If there is no slash in the argv0 path, then we have to * assume python is on the user's $PATH, since there's no * other way to find a directory to start the search from. If * $PATH isn't exported, you lose. */ if (strchr(prog, SEP)) strncpy(progpath, prog, MAXPATHLEN); else if (path) { while (1) { char *delim = strchr(path, DELIM); if (delim) { size_t len = delim - path; if (len > MAXPATHLEN) len = MAXPATHLEN; strncpy(progpath, path, len); *(progpath + len) = '\0'; } else strncpy(progpath, path, MAXPATHLEN); joinpath(progpath, prog); if (isxfile(progpath)) break; if (!delim) { progpath[0] = '\0'; break; } path = delim + 1; } } else progpath[0] = '\0'; if ( (!is_absolute(progpath)) && (progpath[0] != '\0') ) absolutize(progpath); strncpy(argv0_path, progpath, MAXPATHLEN); argv0_path[MAXPATHLEN] = '\0'; set_volume(volume_name, argv0_path); reduce(argv0_path); /* At this point, argv0_path is guaranteed to be less than MAXPATHLEN bytes long. */ /* ########################################################################### Build the FULL prefix string, including volume name. This is the full path to the platform independent libraries. ########################################################################### */ strncpy(prefix, volume_name, MAXPATHLEN); joinpath(prefix, PREFIX); joinpath(prefix, lib_python); /* ########################################################################### Build the FULL path to the zipped-up Python library. ########################################################################### */ strncpy(zip_path, prefix, MAXPATHLEN); zip_path[MAXPATHLEN] = '\0'; reduce(zip_path); joinpath(zip_path, "python00.zip"); bufsz = strlen(zip_path); /* Replace "00" with version */ zip_path[bufsz - 6] = VERSION[0]; zip_path[bufsz - 5] = VERSION[1]; /* ########################################################################### Build the FULL path to dynamically loadable libraries. ########################################################################### */ strncpy(exec_prefix, volume_name, MAXPATHLEN); // "fs0:" joinpath(exec_prefix, EXEC_PREFIX); // "fs0:/Efi/StdLib" joinpath(exec_prefix, lib_python); // "fs0:/Efi/StdLib/lib/python.27" joinpath(exec_prefix, "lib-dynload"); // "fs0:/Efi/StdLib/lib/python.27/lib-dynload" /* ########################################################################### Build the module search path. ########################################################################### */ /* Reduce prefix and exec_prefix to their essence, * e.g. /usr/local/lib/python1.5 is reduced to /usr/local. * If we're loading relative to the build directory, * return the compiled-in defaults instead. */ reduce(prefix); reduce(prefix); /* The prefix is the root directory, but reduce() chopped * off the "/". */ if (!prefix[0]) { strcpy(prefix, volume_name); } bufsz = strlen(prefix); if(prefix[bufsz-1] == ':') { // if prefix consists solely of a volume_name prefix[bufsz] = SEP; // then append SEP indicating the root directory prefix[bufsz+1] = 0; // and ensure the new string is terminated } /* Calculate size of return buffer. */ defpath = pythonpath; bufsz = 0; if (rtpypath) bufsz += strlen(rtpypath) + 1; prefixsz = strlen(prefix) + 1; while (1) { char *delim = strchr(defpath, DELIM); if (is_absolute(defpath) == 0) /* Paths are relative to prefix */ bufsz += prefixsz; if (delim) bufsz += delim - defpath + 1; else { bufsz += strlen(defpath) + 1; break; } defpath = delim + 1; } bufsz += strlen(zip_path) + 1; bufsz += strlen(exec_prefix) + 1; /* This is the only malloc call in this file */ buf = (char *)PyMem_Malloc(bufsz); if (buf == NULL) { /* We can't exit, so print a warning and limp along */ fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n"); fprintf(stderr, "Using default static PYTHONPATH.\n"); module_search_path = PYTHONPATH; } else { /* Run-time value of $PYTHONPATH goes first */ if (rtpypath) { strcpy(buf, rtpypath); strcat(buf, delimiter); } else buf[0] = '\0'; /* Next is the default zip path */ strcat(buf, zip_path); strcat(buf, delimiter); /* Next goes merge of compile-time $PYTHONPATH with * dynamically located prefix. */ defpath = pythonpath; while (1) { char *delim = strchr(defpath, DELIM); if (is_absolute(defpath) != 1) { strcat(buf, prefix); strcat(buf, separator); } if (delim) { size_t len = delim - defpath + 1; size_t end = strlen(buf) + len; strncat(buf, defpath, len); *(buf + end) = '\0'; } else { strcat(buf, defpath); break; } defpath = delim + 1; } strcat(buf, delimiter); /* Finally, on goes the directory for dynamic-load modules */ strcat(buf, exec_prefix); /* And publish the results */ module_search_path = buf; } /* At this point, exec_prefix is set to VOL:/Efi/StdLib/lib/python.27/dynalib. We want to get back to the root value, so we have to remove the final three segments to get VOL:/Efi/StdLib. Because we don't know what VOL is, and EXEC_PREFIX is also indeterminate, we just remove the three final segments. */ reduce(exec_prefix); reduce(exec_prefix); reduce(exec_prefix); if (!exec_prefix[0]) { strcpy(exec_prefix, volume_name); } bufsz = strlen(exec_prefix); if(exec_prefix[bufsz-1] == ':') { exec_prefix[bufsz] = SEP; exec_prefix[bufsz+1] = 0; } if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: module_search_path = \"%s\"\n", __func__, __LINE__, module_search_path); if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: prefix = \"%s\"\n", __func__, __LINE__, prefix); if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: exec_prefix = \"%s\"\n", __func__, __LINE__, exec_prefix); if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: progpath = \"%s\"\n", __func__, __LINE__, progpath); }
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); }