コード例 #1
0
ファイル: binds.c プロジェクト: aculich/singularity
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);
}
コード例 #2
0
ファイル: tmp.c プロジェクト: aculich/singularity
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);
}
コード例 #3
0
ファイル: scratch.c プロジェクト: gmkurtzer/singularity
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;
}
コード例 #4
0
ファイル: userbinds.c プロジェクト: remyd1/singularity
int _singularity_runtime_mount_userbinds(void) {
    char *container_dir = singularity_runtime_rootfs(NULL);
    char *bind_path_string;

    singularity_message(DEBUG, "Checking for environment variable 'SINGULARITY_BINDPATH'\n");
    if ( ( bind_path_string = singularity_registry_get("BINDPATH") ) != NULL ) {

        singularity_message(DEBUG, "Checking for 'user bind control' in config\n");
        if ( singularity_config_get_bool(USER_BIND_CONTROL) <= 0 ) {
            singularity_message(WARNING, "Ignoring user bind request: user bind control is disabled by system administrator\n");
            return(0);
        }

#ifndef SINGULARITY_NO_NEW_PRIVS
        singularity_message(WARNING, "Ignoring user bind request: host does not support PR_SET_NO_NEW_PRIVS\n");
        return(0);
#endif

        singularity_message(DEBUG, "Parsing SINGULARITY_BINDPATH for user-specified bind mounts.\n");
        char *outside_token = NULL;
        char *inside_token = NULL;
        char *current = strtok_r(strdup(bind_path_string), ",", &outside_token);

        free(bind_path_string);

        while ( current != NULL ) {
            int read_only = 0;
            char *source = strtok_r(current, ":", &inside_token);
            char *dest = strtok_r(NULL, ":", &inside_token);
            char *opts = strtok_r(NULL, ":", &inside_token);

            current = strtok_r(NULL, ",", &outside_token);

            if ( dest == NULL ) {
                dest = source;
            }

            singularity_message(DEBUG, "Found bind: %s -> container:%s\n", source, dest);

            if ( opts != NULL ) {
                if ( strcmp(opts, "rw") == 0 ) {
                    // This is the default
                } else if ( strcmp(opts, "ro") == 0 ) {
                    read_only = 1;
                } else {
                    singularity_message(WARNING, "Not mounting requested bind point, invalid mount option %s: %s\n", opts, dest);
                    continue;
                }
            }


            singularity_message(DEBUG, "Checking if bind point is already mounted: %s\n", dest);
            if ( check_mounted(dest) >= 0 ) {
                singularity_message(WARNING, "Not mounting requested bind point (already mounted in container): %s\n", dest);
                continue;
            }

            if ( ( is_file(source) == 0 ) && ( is_file(joinpath(container_dir, dest)) < 0 ) ) {
                if ( singularity_registry_get("OVERLAYFS_ENABLED") != NULL ) {
                    char *dir = dirname(strdup(dest));
                    if ( is_dir(joinpath(container_dir, dir)) < 0 ) {
                        singularity_message(VERBOSE3, "Creating bind directory on overlay file system: %s\n", dest);
                        if ( s_mkpath(joinpath(container_dir, dir), 0755) < 0 ) {
                            singularity_priv_escalate();
                            singularity_message(VERBOSE3, "Retrying with privileges to create bind directory on overlay file system: %s\n", dest);
                            if ( s_mkpath(joinpath(container_dir, dir), 0755) < 0 ) {
                                singularity_message(ERROR, "Could not create basedir for file bind %s: %s\n", dest, strerror(errno));
                                continue;
                            }
                            singularity_priv_drop();
                        }
                    }
                    singularity_priv_escalate();
                    singularity_message(VERBOSE3, "Creating bind file on overlay file system: %s\n", dest);
                    FILE *tmp = fopen(joinpath(container_dir, dest), "w+"); // Flawfinder: ignore
                    singularity_priv_drop();
                    if ( tmp == NULL ) {
                        singularity_message(WARNING, "Skipping user bind, could not create bind point %s: %s\n", dest, strerror(errno));
                        continue;
                    }
                    if ( fclose(tmp) != 0 ) {
                        singularity_message(WARNING, "Skipping user bind, could not close bind point file descriptor %s: %s\n", dest, strerror(errno));
                        continue;
                    }
                    singularity_message(DEBUG, "Created bind file: %s\n", dest);
                } else {
                    singularity_message(WARNING, "Skipping user bind, non existant bind point (file) in container: '%s'\n", dest);
                    continue;
                }
            } else if ( ( is_dir(source) == 0 ) && ( is_dir(joinpath(container_dir, dest)) < 0 ) ) {
                if ( singularity_registry_get("OVERLAYFS_ENABLED") != NULL ) {
                    singularity_message(VERBOSE3, "Creating bind directory on overlay file system: %s\n", dest);
                    if ( s_mkpath(joinpath(container_dir, dest), 0755) < 0 ) {
                        singularity_priv_escalate();
                        singularity_message(VERBOSE3, "Retrying with privileges to create bind directory on overlay file system: %s\n", dest);
                        if ( s_mkpath(joinpath(container_dir, dest), 0755) < 0 ) {
                            singularity_priv_drop();
                            singularity_message(WARNING, "Skipping user bind, could not create bind point %s: %s\n", dest, strerror(errno));
                            continue;
                        }
                        singularity_priv_drop();
                    }
                } else {
                    singularity_message(WARNING, "Skipping user bind, non existant bind point (directory) in container: '%s'\n", dest);
                    continue;
                }
            }

            singularity_priv_escalate();
            singularity_message(VERBOSE, "Binding '%s' to '%s/%s'\n", source, container_dir, dest);
            if ( mount(source, joinpath(container_dir, dest), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) {
                singularity_message(ERROR, "There was an error binding the path %s: %s\n", source, strerror(errno));
                ABORT(255);
            }
            if ( read_only ) {
                if ( singularity_priv_userns_enabled() == 1 ) {
                    singularity_message(WARNING, "Can not make bind mount read only within the user namespace: %s\n", dest);
                } else {
                    singularity_message(VERBOSE, "Remounting %s read-only\n", dest);
                    if ( mount(NULL, joinpath(container_dir, dest), NULL, MS_RDONLY|MS_BIND|MS_NOSUID|MS_REC|MS_REMOUNT, NULL) < 0 ) {
                        singularity_message(ERROR, "There was an error write-protecting the path %s: %s\n", source, strerror(errno));
                        ABORT(255);
                    }
                    if ( access(joinpath(container_dir, dest), W_OK) == 0 || errno != EROFS ) { // Flawfinder: ignore (precautionary confirmation, not necessary)
                        singularity_message(ERROR, "Failed to write-protect the path %s: %s\n", source, strerror(errno));
                        ABORT(255);
                    }
                }
            } else {
                if ( singularity_priv_userns_enabled() <= 0 ) {
                    if ( mount(NULL, joinpath(container_dir, dest), NULL, MS_BIND|MS_NOSUID|MS_REC|MS_REMOUNT, NULL) < 0 ) {
                        singularity_message(ERROR, "There was an error remounting the path %s: %s\n", source, strerror(errno));
                        ABORT(255);
                    }
                }
            }
            singularity_priv_drop();

        }

        singularity_message(DEBUG, "Unsetting environment variable 'SINGULARITY_BINDPATH'\n");
        unsetenv("SINGULARITY_BINDPATH");
    } else {
        singularity_message(DEBUG, "No user bind mounts specified.\n");
    }
    return(0);
}