diff options
| author | Joseph Hunkeler <jhunkeler@users.noreply.github.com> | 2026-06-02 17:04:13 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-06-02 17:04:13 -0400 |
| commit | 252b9646c1cb0538123d51ced4a733f3dcfc266b (patch) | |
| tree | 84b300af068db367bd9f3262487aeef3c7ba22d0 /src | |
| parent | d8ee8c27444a56bb98dd8bd67a019a1e9efbcc10 (diff) | |
| download | stasis-252b9646c1cb0538123d51ced4a733f3dcfc266b.tar.gz | |
Safe strings, finally (#145)
* Add string copy and catonate replacements
* safe_strncpy
* safe_strncat
* Replace string functions
* gbo.ini: Update tweakwcs to 0.9.0
* generic.ini: Update tweakwcs to 0.9.0
Diffstat (limited to 'src')
30 files changed, 230 insertions, 323 deletions
diff --git a/src/cli/stasis/args.c b/src/cli/stasis/args.c index eb096bc..c1bf031 100644 --- a/src/cli/stasis/args.c +++ b/src/cli/stasis/args.c @@ -89,20 +89,20 @@ void usage(char *progname) { char opt_long[50] = {0}; // --? [ARG]? char opt_short[50] = {0}; // -? [ARG]? - strncat(opt_long, "--", sizeof(opt_long) - strlen(opt_long) - 1); - strncat(opt_long, long_options[x].name, sizeof(opt_long) - strlen(opt_long) - 1); + safe_strncat(opt_long, "--", sizeof(opt_long)); + safe_strncat(opt_long, long_options[x].name, sizeof(opt_long)); if (long_options[x].has_arg) { - strncat(opt_long, " ARG", sizeof(opt_long) - strlen(opt_long) - 1); + safe_strncat(opt_long, " ARG", sizeof(opt_long)); } if (long_options[x].val <= 'z') { - strncat(opt_short, "-", sizeof(opt_short) - strlen(opt_short) - 1); + safe_strncat(opt_short, "-", sizeof(opt_short)); opt_short[1] = (char) long_options[x].val; if (long_options[x].has_arg) { - strncat(opt_short, " ARG", sizeof(opt_short) - strlen(opt_short) - 1); + safe_strncat(opt_short, " ARG", sizeof(opt_short)); } } else { - strncat(opt_short, " ", sizeof(opt_short) - strlen(opt_short) - 1); + safe_strncat(opt_short, " ", sizeof(opt_short)); } snprintf(tmp, sizeof(tmp) - strlen(tmp), " %%-%ds\t%%s\t\t%%s", width + 4); diff --git a/src/cli/stasis/stasis_main.c b/src/cli/stasis/stasis_main.c index fb4ed80..e660f6b 100644 --- a/src/cli/stasis/stasis_main.c +++ b/src/cli/stasis/stasis_main.c @@ -17,11 +17,10 @@ static void setup_sysconfdir() { // environment variable char stasis_sysconfdir_tmp[PATH_MAX]; if (getenv("STASIS_SYSCONFDIR")) { - strncpy(stasis_sysconfdir_tmp, getenv("STASIS_SYSCONFDIR"), sizeof(stasis_sysconfdir_tmp) - 1); + safe_strncpy(stasis_sysconfdir_tmp, getenv("STASIS_SYSCONFDIR"), sizeof(stasis_sysconfdir_tmp)); } else { - strncpy(stasis_sysconfdir_tmp, STASIS_SYSCONFDIR, sizeof(stasis_sysconfdir_tmp) - 1); + safe_strncpy(stasis_sysconfdir_tmp, STASIS_SYSCONFDIR, sizeof(stasis_sysconfdir_tmp)); } - stasis_sysconfdir_tmp[sizeof(stasis_sysconfdir_tmp) - 1] = '\0'; globals.sysconfdir = realpath(stasis_sysconfdir_tmp, NULL); if (!globals.sysconfdir) { @@ -567,8 +566,7 @@ int main(int argc, char *argv[]) { globals.continue_on_error = true; break; case 'p': - strncpy(python_override_version, optarg, sizeof(python_override_version) - 1); - python_override_version[sizeof(python_override_version) - 1] = '\0'; + safe_strncpy(python_override_version, optarg, sizeof(python_override_version)); break; case 'l': globals.cpu_limit = strtol(optarg, NULL, 10); @@ -699,22 +697,10 @@ int main(int argc, char *argv[]) { check_requirements(&ctx); configure_jfrog_cli(&ctx); - /* - delivery_free(&ctx); - tpl_free(); - globals_free(); - return 0; - */ - runtime_apply(ctx.runtime.environ); - strncpy(env_name, ctx.info.release_name, sizeof(env_name) - 1); - env_name[sizeof(env_name) - 1] = '\0'; - - strncpy(env_name_testing, env_name, sizeof(env_name_testing) - 1); - env_name_testing[sizeof(env_name_testing) - 1] = '\0'; - - strncat(env_name_testing, "-test", sizeof(env_name_testing) - strlen(env_name_testing) - 1); - env_name_testing[sizeof(env_name_testing) - 1] = '\0'; + safe_strncpy(env_name, ctx.info.release_name, sizeof(env_name)); + safe_strncpy(env_name_testing, env_name, sizeof(env_name_testing)); + safe_strncat(env_name_testing, "-test", sizeof(env_name_testing)); char *envs[] = { "release", env_name, diff --git a/src/cli/stasis_indexer/helpers.c b/src/cli/stasis_indexer/helpers.c index 92e2dd4..3ef96e4 100644 --- a/src/cli/stasis_indexer/helpers.c +++ b/src/cli/stasis_indexer/helpers.c @@ -98,48 +98,46 @@ int pandoc_exec(const char *in_file, const char *out_file, const char *css_file, if (!get_pandoc_version(&pandoc_version)) { // < 2.19 if (pandoc_version < 0x02130000) { - strncat(pandoc_versioned_args, "--self-contained ", sizeof(pandoc_versioned_args) - strlen(pandoc_versioned_args) - 1); + safe_strncat(pandoc_versioned_args, "--self-contained ", sizeof(pandoc_versioned_args)); } else { // >= 2.19 - strncat(pandoc_versioned_args, "--embed-resources ", sizeof(pandoc_versioned_args) - strlen(pandoc_versioned_args) - 1); + safe_strncat(pandoc_versioned_args, "--embed-resources ", sizeof(pandoc_versioned_args)); } // >= 1.15.0.4 if (pandoc_version >= 0x010f0004) { - strncat(pandoc_versioned_args, "--standalone ", sizeof(pandoc_versioned_args) - strlen(pandoc_versioned_args) - 1); + safe_strncat(pandoc_versioned_args, "--standalone ", sizeof(pandoc_versioned_args)); } // >= 1.10.0.1 if (pandoc_version >= 0x010a0001) { - strncat(pandoc_versioned_args, "-f gfm+autolink_bare_uris ", sizeof(pandoc_versioned_args) - strlen(pandoc_versioned_args) - 1); + safe_strncat(pandoc_versioned_args, "-f gfm+autolink_bare_uris ", sizeof(pandoc_versioned_args)); } // > 3.1.9 if (pandoc_version > 0x03010900) { - strncat(pandoc_versioned_args, "-f gfm+alerts ", sizeof(pandoc_versioned_args) - strlen(pandoc_versioned_args) - 1); + safe_strncat(pandoc_versioned_args, "-f gfm+alerts ", sizeof(pandoc_versioned_args)); } } // Converts a markdown file to html char cmd[STASIS_BUFSIZ] = {0}; - strncpy(cmd, "pandoc ", sizeof(cmd) - 1); - cmd[sizeof(cmd) - 1] = '\0'; + safe_strncpy(cmd, "pandoc ", sizeof(cmd)); - strncat(cmd, pandoc_versioned_args, sizeof(cmd) - strlen(cmd) - 1); - cmd[sizeof(cmd) - 1] = '\0'; + safe_strncat(cmd, pandoc_versioned_args, sizeof(cmd)); if (css_file && strlen(css_file)) { - strncat(cmd, "--css ", sizeof(cmd) - strlen(cmd) - 1); - strncat(cmd, css_file, sizeof(cmd) - strlen(cmd) - 1); + safe_strncat(cmd, "--css ", sizeof(cmd)); + safe_strncat(cmd, css_file, sizeof(cmd)); } - strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1); - strncat(cmd, "--metadata title=\"", sizeof(cmd) - strlen(cmd) - 1); - strncat(cmd, title, sizeof(cmd) - strlen(cmd) - 1); - strncat(cmd, "\" ", sizeof(cmd) - strlen(cmd) - 1); - strncat(cmd, "-o ", sizeof(cmd) - strlen(cmd) - 1); - strncat(cmd, out_file, sizeof(cmd) - strlen(cmd) - 1); - strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1); - strncat(cmd, in_file, sizeof(cmd) - strlen(cmd) - 1); + safe_strncat(cmd, " ", sizeof(cmd)); + safe_strncat(cmd, "--metadata title=\"", sizeof(cmd)); + safe_strncat(cmd, title, sizeof(cmd)); + safe_strncat(cmd, "\" ", sizeof(cmd)); + safe_strncat(cmd, "-o ", sizeof(cmd)); + safe_strncat(cmd, out_file, sizeof(cmd)); + safe_strncat(cmd, " ", sizeof(cmd)); + safe_strncat(cmd, in_file, sizeof(cmd)); if (globals.verbose) { puts(cmd); @@ -406,11 +404,10 @@ int write_manifest(const char *path, char **exclude_path, FILE *fp) { continue; } char filepath[PATH_MAX] = {0}; - strncpy(filepath, path, PATH_MAX - 1); - filepath[PATH_MAX - 1] = '\0'; + safe_strncpy(filepath, path, PATH_MAX); - strncat(filepath, "/", sizeof(filepath) - strlen(filepath) - 1); - strncat(filepath, rec->d_name, sizeof(filepath) - strlen(filepath) - 1); + safe_strncat(filepath, "/", sizeof(filepath)); + safe_strncat(filepath, rec->d_name, sizeof(filepath)); if (rec->d_type == DT_DIR) { write_manifest(filepath, exclude_path, fp); diff --git a/src/cli/stasis_indexer/junitxml_report.c b/src/cli/stasis_indexer/junitxml_report.c index a7dcd06..300b7e5 100644 --- a/src/cli/stasis_indexer/junitxml_report.c +++ b/src/cli/stasis_indexer/junitxml_report.c @@ -55,8 +55,7 @@ static int write_report_output(struct Delivery *ctx, FILE *destfp, const char *x } char short_name[PATH_MAX] = {0}; - strncpy(short_name, bname, sizeof(short_name) - 1); - short_name[sizeof(short_name) - 1] = '\0'; + safe_strncpy(short_name, bname, sizeof(short_name)); replace_text(short_name, short_name_pattern, "", 0); replace_text(short_name, "results-", "", 0); diff --git a/src/cli/stasis_indexer/stasis_indexer_main.c b/src/cli/stasis_indexer/stasis_indexer_main.c index e87122e..45bbb6c 100644 --- a/src/cli/stasis_indexer/stasis_indexer_main.c +++ b/src/cli/stasis_indexer/stasis_indexer_main.c @@ -13,14 +13,11 @@ int indexer_combine_rootdirs(const char *dest, char **rootdirs, const size_t roo char destdir_with_output[PATH_MAX] = {0}; char *destdir = destdir_bare; - strncpy(destdir_bare, dest, sizeof(destdir_bare) - 1); - destdir[sizeof(destdir_bare) - 1] = '\0'; + safe_strncpy(destdir_bare, dest, sizeof(destdir_bare)); - strncpy(destdir_with_output, dest, sizeof(destdir_with_output) - 1); - destdir_with_output[sizeof(destdir_with_output) - 1] = '\0'; + safe_strncpy(destdir_with_output, dest, sizeof(destdir_with_output)); - strncat(destdir_with_output, "/output", sizeof(destdir_with_output) - strlen(destdir_with_output) - 1); - destdir_with_output[sizeof(destdir_with_output) - 1] = '\0'; + safe_strncat(destdir_with_output, "/output", sizeof(destdir_with_output)); if (!access(destdir_with_output, F_OK)) { destdir = destdir_with_output; @@ -31,14 +28,11 @@ int indexer_combine_rootdirs(const char *dest, char **rootdirs, const size_t roo char srcdir_bare[PATH_MAX] = {0}; char srcdir_with_output[PATH_MAX] = {0}; char *srcdir = srcdir_bare; - strncpy(srcdir_bare, rootdirs[i], sizeof(srcdir_bare) - 1); - srcdir_bare[sizeof(srcdir_bare) - 1] = '\0'; + safe_strncpy(srcdir_bare, rootdirs[i], sizeof(srcdir_bare)); - strncpy(srcdir_with_output, rootdirs[i], sizeof(srcdir_with_output) - 1); - srcdir_with_output[sizeof(srcdir_with_output) - 1] = '\0'; + safe_strncpy(srcdir_with_output, rootdirs[i], sizeof(srcdir_with_output)); - strncat(srcdir_with_output, "/output", sizeof(srcdir_with_output) - strlen(srcdir_with_output) - 1); - srcdir_with_output[sizeof(srcdir_with_output) - 1] = '\0'; + safe_strncat(srcdir_with_output, "/output", sizeof(srcdir_with_output)); if (access(srcdir_bare, F_OK)) { SYSWARN("%s does not exist", srcdir_bare); @@ -266,11 +260,10 @@ int main(const int argc, char *argv[]) { char stasis_sysconfdir_tmp[PATH_MAX]; if (getenv("STASIS_SYSCONFDIR")) { - strncpy(stasis_sysconfdir_tmp, getenv("STASIS_SYSCONFDIR"), sizeof(stasis_sysconfdir_tmp) - 1); + safe_strncpy(stasis_sysconfdir_tmp, getenv("STASIS_SYSCONFDIR"), sizeof(stasis_sysconfdir_tmp)); } else { - strncpy(stasis_sysconfdir_tmp, STASIS_SYSCONFDIR, sizeof(stasis_sysconfdir_tmp) - 1); + safe_strncpy(stasis_sysconfdir_tmp, STASIS_SYSCONFDIR, sizeof(stasis_sysconfdir_tmp)); } - stasis_sysconfdir_tmp[sizeof(stasis_sysconfdir_tmp) - 1] = '\0'; globals.sysconfdir = realpath(stasis_sysconfdir_tmp, NULL); if (!globals.sysconfdir) { @@ -281,9 +274,9 @@ int main(const int argc, char *argv[]) { char workdir_template[PATH_MAX] = {0}; const char *system_tmp = getenv("TMPDIR"); if (system_tmp) { - strncat(workdir_template, system_tmp, sizeof(workdir_template) - strlen(workdir_template) - 1); + safe_strncat(workdir_template, system_tmp, sizeof(workdir_template)); } else { - strncat(workdir_template, "/tmp/stasis", sizeof(workdir_template) - strlen(workdir_template) - 1); + safe_strncat(workdir_template, "/tmp/stasis", sizeof(workdir_template)); } if (mkdirs(workdir_template, 0700)) { @@ -291,7 +284,7 @@ int main(const int argc, char *argv[]) { exit(1); } - strncat(workdir_template, "/stasis-combine.XXXXXX", sizeof(workdir_template) - strlen(workdir_template) - 1); + safe_strncat(workdir_template, "/stasis-combine.XXXXXX", sizeof(workdir_template)); char *workdir = mkdtemp(workdir_template); if (!workdir) { SYSERROR("Unable to create temporary directory: %s", workdir_template); diff --git a/src/cli/stasis_indexer/website.c b/src/cli/stasis_indexer/website.c index 07ad6ad..edab735 100644 --- a/src/cli/stasis_indexer/website.c +++ b/src/cli/stasis_indexer/website.c @@ -35,9 +35,7 @@ int indexer_make_website(struct Delivery **ctx) { } // Replace *.md extension with *.html. - strncpy(fullpath_dest, fullpath_src, sizeof(fullpath_dest) - 1); - fullpath_dest[sizeof(fullpath_dest) - 1] = '\0'; - + safe_strncpy(fullpath_dest, fullpath_src, sizeof(fullpath_dest)); gen_file_extension_str(fullpath_dest, sizeof(fullpath_dest), ".html"); // Convert markdown to html @@ -54,8 +52,7 @@ int indexer_make_website(struct Delivery **ctx) { if (!strcmp(filename, "README.md")) { char link_from[PATH_MAX] = {0}; char link_dest[PATH_MAX] = {0}; - strncpy(link_from, "README.html", sizeof(link_from) - 1); - link_dest[sizeof(link_dest) - 1] = '\0'; + safe_strncpy(link_from, "README.html", sizeof(link_from)); snprintf(link_dest, sizeof(link_dest), "%s/%s", root, "index.html"); if (symlink(link_from, link_dest)) { SYSWARN("symlink(%s, %s) failed: %s", link_from, link_dest, strerror(errno)); diff --git a/src/lib/core/artifactory.c b/src/lib/core/artifactory.c index d4b48fb..db6fbbe 100644 --- a/src/lib/core/artifactory.c +++ b/src/lib/core/artifactory.c @@ -25,18 +25,15 @@ int artifactory_download_cli(char *dest, // convert platform string to lower-case SYSDEBUG("Set os_ident"); - strncpy(os_ident, os, sizeof(os_ident) - 1); - os_ident[sizeof(os_ident) - 1] = '\0'; + safe_strncpy(os_ident, os, sizeof(os_ident)); tolower_s(os_ident); SYSDEBUG("os_ident=%s", os_ident); // translate OS identifier if (!strcmp(os_ident, "darwin") || startswith(os_ident, "macos")) { - strncpy(os_ident, "mac", sizeof(os_ident) - 1); - os_ident[sizeof(os_ident) - 1] = '\0'; + safe_strncpy(os_ident, "mac", sizeof(os_ident)); } else if (!strcmp(os_ident, "linux")) { - strncpy(os_ident, "linux", sizeof(os_ident) - 1); - os_ident[sizeof(os_ident) - 1] = '\0'; + safe_strncpy(os_ident, "linux", sizeof(os_ident)); } else { SYSERROR("unknown operating system: %s", os_ident); return -1; @@ -44,25 +41,23 @@ int artifactory_download_cli(char *dest, // translate ARCH identifier SYSDEBUG("Set arch_ident"); - strncpy(arch_ident, arch, sizeof(arch_ident) - 1); - arch_ident[sizeof(arch_ident) - 1] = '\0'; + safe_strncpy(arch_ident, arch, sizeof(arch_ident)); SYSDEBUG("arch_ident=%s", arch_ident); if (startswith(arch_ident, "i") && endswith(arch_ident, "86")) { - strncpy(arch_ident, "386", sizeof(arch_ident) - 1); + safe_strncpy(arch_ident, "386", sizeof(arch_ident)); } else if (!strcmp(arch_ident, "amd64") || !strcmp(arch_ident, "x86_64") || !strcmp(arch_ident, "x64")) { if (!strcmp(os_ident, "mac")) { - strncpy(arch_ident, "386", sizeof(arch_ident) - 1); + safe_strncpy(arch_ident, "386", sizeof(arch_ident)); } else { - strncpy(arch_ident, "amd64", sizeof(arch_ident) - 1); + safe_strncpy(arch_ident, "amd64", sizeof(arch_ident)); } } else if (!strcmp(arch_ident, "arm64") || !strcmp(arch_ident, "aarch64")) { - strncpy(arch_ident, "arm64", sizeof(arch_ident) - 1); + safe_strncpy(arch_ident, "arm64", sizeof(arch_ident)); } else { SYSERROR("unknown architecture: %s", arch_ident); return -1; } - arch_ident[sizeof(arch_ident) - 1] = '\0'; SYSDEBUG("Construct URL"); @@ -75,8 +70,7 @@ int artifactory_download_cli(char *dest, os_ident, // ... arch_ident, // jfrog-cli-linux-x86_64 remote_filename); // jf - strncpy(path, dest, sizeof(path) - 1); - path[sizeof(path) - 1] = '\0'; + safe_strncpy(path, dest, sizeof(path)); if (mkdirs(path, 0755)) { SYSERROR("%s: %s", path, strerror(errno)); @@ -272,11 +266,9 @@ int jfrog_cli(struct JFRT_Auth *auth, const char *subsystem, const char *task, c } if (!globals.verbose) { - strncpy(proc.f_stdout, "/dev/null", sizeof(proc.f_stdout) - 1); - proc.f_stdout[sizeof(proc.f_stdout) - 1] = '\0'; + safe_strncpy(proc.f_stdout, "/dev/null", sizeof(proc.f_stdout)); - strncpy(proc.f_stderr, "/dev/null", sizeof(proc.f_stderr) - 1); - proc.f_stderr[sizeof(proc.f_stderr) - 1] = '\0'; + safe_strncpy(proc.f_stderr, "/dev/null", sizeof(proc.f_stderr)); } return shell(&proc, cmd); } @@ -444,7 +436,7 @@ int jfrog_cli_rt_upload(struct JFRT_Auth *auth, struct JFRT_Upload *ctx, char *s if (base) { src = base; } else { - strncat(src, "/", sizeof(src) - strlen(src) - 1); + safe_strncat(src, "/", sizeof(src)); } pushd(new_src); } diff --git a/src/lib/core/conda.c b/src/lib/core/conda.c index 6083023..c9eb750 100644 --- a/src/lib/core/conda.c +++ b/src/lib/core/conda.c @@ -3,6 +3,7 @@ // #include "conda.h" +#include "version_compare.h" int micromamba(const struct MicromambaInfo *info, char *command, ...) { struct utsname sys; @@ -10,13 +11,11 @@ int micromamba(const struct MicromambaInfo *info, char *command, ...) { tolower_s(sys.sysname); if (!strcmp(sys.sysname, "darwin")) { - strncpy(sys.sysname, "osx", sizeof(sys.sysname) - 1); - sys.sysname[sizeof(sys.sysname) - 1] = '\0'; + safe_strncpy(sys.sysname, "osx", sizeof(sys.sysname)); } if (!strcmp(sys.machine, "x86_64")) { - strncpy(sys.machine, "64", sizeof(sys.machine) - 1); - sys.machine[sizeof(sys.machine) - 1] = '\0'; + safe_strncpy(sys.machine, "64", sizeof(sys.machine)); } if (!info->download_dir || isempty(info->download_dir)) { @@ -99,6 +98,7 @@ int micromamba(const struct MicromambaInfo *info, char *command, ...) { } setenv("CONDARC", rcpath, 1); + setenv("MAMBARC", rcpath, 1); setenv("MAMBA_ROOT_PREFIX", info->conda_prefix, 1); int status = system(cmd); unsetenv("MAMBA_ROOT_PREFIX"); @@ -160,8 +160,7 @@ int pkg_index_provides(int mode, const char *index, const char *spec, const char } // Normalize the local spec string - strncpy(spec_local, spec, sizeof(spec_local) - 1); - spec_local[sizeof(spec_local) - 1] = '\0'; + safe_strncpy(spec_local, spec, sizeof(spec_local)); tolower_s(spec_local); lstrip(spec_local); strip(spec_local); @@ -189,15 +188,13 @@ int pkg_index_provides(int mode, const char *index, const char *spec, const char if (mode == PKG_USE_PIP) { // Do an installation in dry-run mode to see if the package exists in the given index. // The --force argument ignores local installation and cache, and actually polls the remote index(es) - strncpy(cmd, "python -m pip install --force --dry-run --no-cache --no-deps ", sizeof(cmd) - 1); - cmd[sizeof(cmd) - 1] = '\0'; + safe_strncpy(cmd, "python -m pip install --force --dry-run --no-cache --no-deps ", sizeof(cmd)); if (index) { snprintf(cmd + strlen(cmd), sizeof(cmd) - strlen(cmd), "--index-url='%s' ", index); } snprintf(cmd + strlen(cmd), sizeof(cmd) - strlen(cmd), "'%s' ", spec_local); } else if (mode == PKG_USE_CONDA) { - strncpy(cmd, "mamba search ", sizeof(cmd) - 1); - cmd[sizeof(cmd) - 1] = '\0'; + safe_strncpy(cmd, "mamba search ", sizeof(cmd)); if (index) { snprintf(cmd + strlen(cmd), sizeof(cmd) - strlen(cmd), "--channel '%s' ", index); @@ -271,14 +268,13 @@ int conda_exec(const char *args) { }; char conda_as[10] = {0}; - strncpy(conda_as, "conda", sizeof(conda_as) - 1); + safe_strncpy(conda_as, "conda", sizeof(conda_as)); for (size_t i = 0; mamba_commands[i] != NULL; i++) { if (startswith(args, mamba_commands[i])) { - strncpy(conda_as, "mamba", sizeof(conda_as) - 1); + safe_strncpy(conda_as, "mamba", sizeof(conda_as)); break; } } - conda_as[sizeof(conda_as) - 1] = '\0'; const char *command_fmt = "%s %s"; @@ -385,8 +381,7 @@ int conda_activate(const char *root, const char *env_name) { close(fd); // Configure our process for output to a log file - strncpy(proc.f_stdout, logfile, sizeof(proc.f_stdout) - 1); - proc.f_stdout[sizeof(proc.f_stdout) - 1] = '\0'; + safe_strncpy(proc.f_stdout, logfile, sizeof(proc.f_stdout)); // Verify conda's init scripts are available if (access(path_conda, F_OK) < 0) { @@ -450,6 +445,7 @@ int conda_activate(const char *root, const char *env_name) { if (env0_to_runtime(logfile) < 0) { return -1; } + remove(logfile); return 0; } @@ -459,22 +455,21 @@ int conda_check_required() { struct StrList *result = NULL; char cmd[PATH_MAX] = {0}; const char *conda_minimum_viable_tools[] = { - "boa", "conda-build", NULL }; // Construct a "conda list" command that searches for all required packages // using conda's (python's) regex matching - strncat(cmd, "conda list '", sizeof(cmd) - strlen(cmd) - 1); + safe_strncat(cmd, "conda list '", sizeof(cmd)); for (size_t i = 0; conda_minimum_viable_tools[i] != NULL; i++) { - strncat(cmd, "^", sizeof(cmd) - strlen(cmd) - 1); - strncat(cmd, conda_minimum_viable_tools[i], sizeof(cmd) - strlen(cmd) - 1); + safe_strncat(cmd, "^", sizeof(cmd)); + safe_strncat(cmd, conda_minimum_viable_tools[i], sizeof(cmd)); if (conda_minimum_viable_tools[i + 1] != NULL) { - strncat(cmd, "|", sizeof(cmd) - strlen(cmd) - 1); + safe_strncat(cmd, "|", sizeof(cmd)); } } - strncat(cmd, "' | cut -d ' ' -f 1", sizeof(cmd) - strlen(cmd) - 1); + safe_strncat(cmd, "' | cut -d ' ' -f 1", sizeof(cmd)); // Verify all required packages are installed char *cmd_out = shell_output(cmd, &status); @@ -530,8 +525,7 @@ int conda_setup_headless() { const char *cmd_fmt = "'%s'"; if (globals.conda_packages && strlist_count(globals.conda_packages)) { memset(cmd, 0, sizeof(cmd)); - strncpy(cmd, "install ", sizeof(cmd) - 1); - cmd[sizeof(cmd) - 1] = '\0'; + safe_strncpy(cmd, "install ", sizeof(cmd)); total = strlist_count(globals.conda_packages); for (size_t i = 0; i < total; i++) { @@ -542,7 +536,7 @@ int conda_setup_headless() { snprintf(cmd + strlen(cmd), sizeof(cmd) - strlen(cmd), cmd_fmt, item); if (i < total - 1) { - strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1); + safe_strncat(cmd, " ", sizeof(cmd)); } } @@ -554,8 +548,7 @@ int conda_setup_headless() { if (globals.pip_packages && strlist_count(globals.pip_packages)) { memset(cmd, 0, sizeof(cmd)); - strncpy(cmd, "install ", sizeof(cmd) - 1); - cmd[sizeof(cmd) - 1] = '\0'; + safe_strncpy(cmd, "install ", sizeof(cmd)); total = strlist_count(globals.pip_packages); for (size_t i = 0; i < total; i++) { @@ -565,7 +558,7 @@ int conda_setup_headless() { } snprintf(cmd + strlen(cmd), sizeof(cmd) - strlen(cmd), cmd_fmt, item); if (i < total - 1) { - strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1); + safe_strncat(cmd, " ", sizeof(cmd)); } } @@ -613,7 +606,7 @@ int conda_env_create_from_uri(char *name, char *uri, char *python_version) { unlink(tempfile); // We'll create a new file with the same random bits, ending with .yml - strncat(tempfile, ".yml", sizeof(tempfile) - strlen(tempfile) - 1); + safe_strncat(tempfile, ".yml", sizeof(tempfile)); char *errmsg = NULL; const long http_code = download(uri_fs ? uri_fs : uri, tempfile, &errmsg); if (HTTP_ERROR(http_code)) { diff --git a/src/lib/core/copy.c b/src/lib/core/copy.c index 7666e67..f11f919 100644 --- a/src/lib/core/copy.c +++ b/src/lib/core/copy.c @@ -14,8 +14,7 @@ int copy2(const char *src, const char *dest, unsigned int op) { } char dname[1024] = {0}; - strncpy(dname, dest, sizeof(dname) - 1); - dname[sizeof(dname) - 1] = '\0'; + safe_strncpy(dname, dest, sizeof(dname)); char *dname_endptr = strrchr(dname, '/'); if (dname_endptr != NULL) { diff --git a/src/lib/core/docker.c b/src/lib/core/docker.c index 484f476..84fdfd5 100644 --- a/src/lib/core/docker.c +++ b/src/lib/core/docker.c @@ -18,12 +18,10 @@ int docker_exec(const char *args, const unsigned flags) { } if (final_flags & STASIS_DOCKER_QUIET_STDOUT) { - strncpy(proc.f_stdout, "/dev/null", sizeof(proc.f_stdout) - 1); - proc.f_stdout[sizeof(proc.f_stdout) - 1] = '\0'; + safe_strncpy(proc.f_stdout, "/dev/null", sizeof(proc.f_stdout)); } if (final_flags & STASIS_DOCKER_QUIET_STDERR) { - strncpy(proc.f_stderr, "/dev/null", sizeof(proc.f_stderr) - 1); - proc.f_stderr[sizeof(proc.f_stderr) - 1] = '\0'; + safe_strncpy(proc.f_stderr, "/dev/null", sizeof(proc.f_stderr)); } if (!final_flags) { @@ -71,12 +69,11 @@ int docker_build(const char *dirpath, const char *args, int engine) { memset(cmd, 0, sizeof(cmd)); if (engine & STASIS_DOCKER_BUILD) { - strncpy(build, "build", sizeof(build) - 1); + safe_strncpy(build, "build", sizeof(build)); } if (engine & STASIS_DOCKER_BUILD_X) { - strncpy(build, "buildx build", sizeof(build) - 1); + safe_strncpy(build, "buildx build", sizeof(build)); } - build[sizeof(build) - 1] = '\0'; snprintf(cmd, sizeof(cmd), "%s %s %s", build, args, dirpath); return docker_exec(cmd, 0); @@ -88,17 +85,16 @@ int docker_save(const char *image, const char *destdir, const char *compression_ if (compression_program && strlen(compression_program)) { char ext[255] = {0}; if (startswith(compression_program, "zstd")) { - strncpy(ext, "zst", sizeof(ext) - 1); + safe_strncpy(ext, "zst", sizeof(ext)); } else if (startswith(compression_program, "xz")) { - strncpy(ext, "xz", sizeof(ext) - 1); + safe_strncpy(ext, "xz", sizeof(ext)); } else if (startswith(compression_program, "gzip")) { - strncpy(ext, "gz", sizeof(ext) - 1); + safe_strncpy(ext, "gz", sizeof(ext)); } else if (startswith(compression_program, "bzip2")) { - strncpy(ext, "bz2", sizeof(ext) - 1); + safe_strncpy(ext, "bz2", sizeof(ext)); } else { - strncpy(ext, compression_program, sizeof(ext) - 1); + safe_strncpy(ext, compression_program, sizeof(ext)); } - ext[sizeof(ext) - 1] = '\0'; snprintf(cmd, sizeof(cmd), "save \"%s\" | %s > \"%s/%s.tar.%s\"", image, compression_program, destdir, image, ext); } else { snprintf(cmd, sizeof(cmd), "save \"%s\" -o \"%s/%s.tar\"", image, destdir, image); @@ -126,11 +122,9 @@ static char *docker_ident() { } memset(&proc, 0, sizeof(proc)); - strncpy(proc.f_stdout, tempfile, sizeof(proc.f_stdout) - 1); - proc.f_stdout[sizeof(proc.f_stdout) - 1] = '\0'; + safe_strncpy(proc.f_stdout, tempfile, sizeof(proc.f_stdout)); - strncpy(proc.f_stderr, "/dev/null", sizeof(proc.f_stderr) - 1); - proc.f_stderr[sizeof(proc.f_stderr) - 1] = '\0'; + safe_strncpy(proc.f_stderr, "/dev/null", sizeof(proc.f_stderr)); shell(&proc, "docker --version"); diff --git a/src/lib/core/environment.c b/src/lib/core/environment.c index 4258004..4623db8 100644 --- a/src/lib/core/environment.c +++ b/src/lib/core/environment.c @@ -80,17 +80,16 @@ void runtime_export(RuntimeEnv *env, char **keys) { for (size_t i = 0; borne[i] != NULL; i++) { if (strcmp(sh, borne[i]) == 0) { - strncpy(export_command, "export", sizeof(export_command) - 1); + safe_strncpy(export_command, "export", sizeof(export_command)); break; } } for (size_t i = 0; unborne[i] != NULL; i++) { if (strcmp(sh, unborne[i]) == 0) { - strncpy(export_command, "setenv", sizeof(export_command) - 1); + safe_strncpy(export_command, "setenv", sizeof(export_command)); break; } } - export_command[sizeof(export_command) - 1] = '\0'; for (size_t i = 0; i < strlist_count(env); i++) { char output[STASIS_BUFSIZ] = {0}; @@ -309,7 +308,7 @@ char *runtime_expand_var(RuntimeEnv *env, char *input) { // Handle literal statement "$$var" // Value becomes "$var" (unexpanded) if (strncmp(&input[i], delim_literal, strlen(delim_literal)) == 0) { - strncat(expanded, &delim, 2); + safe_strncat(expanded, &delim, 2); i += strlen(delim_literal); // Ignore opening brace if (input[i] == '{') { @@ -356,7 +355,7 @@ char *runtime_expand_var(RuntimeEnv *env, char *input) { continue; } // Append expanded environment variable to output - strncat(expanded, tmp, STASIS_BUFSIZ - 1); + safe_strncat(expanded, tmp, STASIS_BUFSIZ); guard_free(tmp); } diff --git a/src/lib/core/github.c b/src/lib/core/github.c index 992ab32..6a8d9e9 100644 --- a/src/lib/core/github.c +++ b/src/lib/core/github.c @@ -113,7 +113,7 @@ int get_github_release_notes(const char *api_token, const char *repo, const char // Extract release notes *output = calloc(strlen(data_offset) + 1, sizeof(**output)); // Copy output (including terminator) - strncpy(*output, data_offset, strlen(data_offset) + 1); + safe_strncpy(*output, data_offset, strlen(data_offset) + 1); } else if ((data_offset = strstr(line, field_message))) { // Skip past the message field data_offset += strlen(field_message); diff --git a/src/lib/core/include/str.h b/src/lib/core/include/str.h index 3e7c3a4..2f86242 100644 --- a/src/lib/core/include/str.h +++ b/src/lib/core/include/str.h @@ -324,4 +324,7 @@ char *to_short_version(const char *s); void unindent(char *s); +int safe_strncpy(char *dst, const char *src, size_t dsize); +int safe_strncat(char *dst, const char *src, size_t dsize); + #endif //STASIS_STR_H diff --git a/src/lib/core/ini.c b/src/lib/core/ini.c index 3c0377f..e727511 100644 --- a/src/lib/core/ini.c +++ b/src/lib/core/ini.c @@ -183,8 +183,7 @@ int ini_getval(struct INIFILE *ini, char *section_name, char *key, int type, int case INIVAL_TYPE_STR_ARRAY: // TODO: data_copy should be at least equal to the length of the data. The use of STASIS_BUFSIZ below is // the root cause of crashes when stasis reads long arrays. - strncpy(tbufp, data_copy, sizeof(tbuf) - 1); - tbuf[sizeof(tbuf) - 1] = '\0'; + safe_strncpy(tbufp, data_copy, sizeof(tbuf)); guard_free(data_copy); data_copy = calloc(STASIS_BUFSIZ, sizeof(*data_copy)); @@ -194,11 +193,10 @@ int ini_getval(struct INIFILE *ini, char *section_name, char *key, int type, int while ((token = strsep(&tbufp, "\n")) != NULL) { //lstrip(token); if (!isempty(token)) { - strncat(data_copy, token, STASIS_BUFSIZ - strlen(data_copy) - 1); - strncat(data_copy, "\n", STASIS_BUFSIZ - strlen(data_copy) - 1); + safe_strncat(data_copy, token, STASIS_BUFSIZ); + safe_strncat(data_copy, "\n", STASIS_BUFSIZ); } } - data_copy[STASIS_BUFSIZ - 1] = '\0'; strip(data_copy); result->as_char_p = strdup(data_copy); break; @@ -359,7 +357,7 @@ int ini_data_append(struct INIFILE **ini, char *section_name, char *key, char *v } size_t value_len_old = strlen(data->value); size_t value_len = strlen(value); - size_t value_len_new = value_len_old + value_len; + size_t value_len_new = value_len_old + value_len + 1; char *value_tmp = NULL; value_tmp = realloc(data->value, value_len_new + 2); if (!value_tmp) { @@ -368,7 +366,7 @@ int ini_data_append(struct INIFILE **ini, char *section_name, char *key, char *v } data->value = value_tmp; - strncat(data->value, value, value_len_new - strlen(data->value)); + safe_strncat(data->value, value, value_len_new); } return 0; } @@ -559,8 +557,7 @@ struct INIFILE *ini_open(const char *filename) { ini = NULL; return NULL; } - strncpy(current_section, "default", sizeof(current_section) - 1); - current_section[sizeof(current_section) - 1] = '\0'; + safe_strncpy(current_section, "default", sizeof(current_section)); // Open the configuration file for reading FILE *fp = fopen(filename, "r"); @@ -640,8 +637,7 @@ struct INIFILE *ini_open(const char *filename) { // Record the name of the section. This is used until another section is found. memset(current_section, 0, sizeof(current_section)); - strncpy(current_section, section_name, sizeof(current_section) - 1); - current_section[sizeof(current_section) - 1] = '\0'; + safe_strncpy(current_section, section_name, sizeof(current_section)); guard_free(section_name); memset(line, 0, sizeof(line)); @@ -664,22 +660,19 @@ struct INIFILE *ini_open(const char *filename) { const size_t key_len = operator - line; memset(key, 0, key_size); - strncpy(key, line, key_len); - key[key_size - 1] = '\0'; + safe_strncpy(key, line, key_len + 1); lstrip(key); strip(key); memset(key_last, 0, key_last_size); - strncpy(key_last, key, key_last_size - 1); - key_last[key_last_size - 1] = '\0'; + safe_strncpy(key_last, key, key_last_size + 1); reading_value = 1; if (strlen(operator) > 1) { - strncpy(value, &operator[1], sizeof(value) - 1); + safe_strncpy(value, &operator[1], sizeof(value)); } else { - strncpy(value, "", sizeof(value) - 1); + safe_strncpy(value, "", sizeof(value)); } - value[sizeof(value) - 1] = '\0'; if (isempty(value)) { //printf("%s is probably long raw data\n", key); @@ -693,10 +686,8 @@ struct INIFILE *ini_open(const char *filename) { } strip(value); } else { - strncpy(key, key_last, key_size - 1); - key[key_size - 1] = '\0'; - strncpy(value, line, sizeof(value) - 1); - value[sizeof(value) - 1] = '\0'; + safe_strncpy(key, key_last, key_size + 1); + safe_strncpy(value, line, sizeof(value)); } memset(line, 0, sizeof(line)); diff --git a/src/lib/core/multiprocessing.c b/src/lib/core/multiprocessing.c index b17bdc1..6c64888 100644 --- a/src/lib/core/multiprocessing.c +++ b/src/lib/core/multiprocessing.c @@ -198,7 +198,7 @@ struct MultiProcessingTask *mp_pool_task(struct MultiProcessingPool *pool, const if (globals.enable_task_logging) { snprintf(slot->log_file, sizeof(slot->log_file), "%s", pool->log_root); // FORTIFY_SOURCE won't leave snprintf alone. The chance for truncation is slim anyway. - strncat(slot->log_file, "/", sizeof(slot->log_file) - strlen(slot->log_file)); + safe_strncat(slot->log_file, "/", sizeof(slot->log_file)); } else { snprintf(slot->log_file, sizeof(slot->log_file), "/dev/stdout"); } diff --git a/src/lib/core/recipe.c b/src/lib/core/recipe.c index 0ee1ef8..8cc8e21 100644 --- a/src/lib/core/recipe.c +++ b/src/lib/core/recipe.c @@ -16,8 +16,7 @@ int recipe_clone(char *recipe_dir, char *url, char *gitref, char **result) { return -1; } } - strncpy(*result, destdir, PATH_MAX - 1); - (*result)[PATH_MAX - 1] = '\0'; + safe_strncpy(*result, destdir, PATH_MAX); if (!access(destdir, F_OK)) { if (!strcmp(destdir, "/")) { diff --git a/src/lib/core/relocation.c b/src/lib/core/relocation.c index 8204101..6afd198 100644 --- a/src/lib/core/relocation.c +++ b/src/lib/core/relocation.c @@ -10,7 +10,7 @@ * ~~~{.c} * size_t str_maxlen = 100; * char *str = calloc(str_maxlen, sizeof(char)); - * strncpy(str, "This are a test.", str_maxlen - 1); + * safe_strncpy(str, "This are a test.", str_maxlen); * if (replace_text(str, "are", "is")) { * fprintf(stderr, "string replacement failed\n"); * exit(1); @@ -84,6 +84,7 @@ int replace_text(char *original, const char *target, const char *replacement, un // truncate whatever remains of the original buffer memset(original + buffer_len, 0, original_len - buffer_len); } + // replace original with contents of buffer strncpy(original, buffer, buffer_len + 1); original[buffer_len] = '\0'; diff --git a/src/lib/core/str.c b/src/lib/core/str.c index c31ce5e..a04293f 100644 --- a/src/lib/core/str.c +++ b/src/lib/core/str.c @@ -78,9 +78,8 @@ void strchrdel(char *sptr, const char *chars) { for (size_t i = 0; i < strlen(chars); i++) { char ch[2] = {0}; - strncpy(ch, &chars[i], 1); - ch[sizeof(ch) - 1] = '\0'; - replace_text(sptr, ch, "", 0); + safe_strncpy(ch, &chars[i], sizeof(ch)); + replace_text(sptr, (char *) ch, "", 0); } } @@ -137,8 +136,7 @@ char** split(char *_sptr, const char* delim, size_t max) guard_array_n_free(result, i); return NULL; } - strncpy(result[i], token, STASIS_BUFSIZ - 1); - result[i][STASIS_BUFSIZ - 1] = '\0'; + safe_strncpy(result[i], token, STASIS_BUFSIZ); } // pos is non-zero when maximum split is reached @@ -150,8 +148,7 @@ char** split(char *_sptr, const char* delim, size_t max) guard_array_n_free(result, i); return NULL; } - strncpy(result[i], &orig[pos], STASIS_BUFSIZ - 1); - result[i][STASIS_BUFSIZ - 1] = '\0'; + safe_strncpy(result[i], &orig[pos], STASIS_BUFSIZ); } guard_free(sptr); @@ -175,9 +172,9 @@ char *join(char **arr, const char *separator) { result = (char *)calloc(total_bytes, sizeof(char)); for (int i = 0; i < records; i++) { - strncat(result, arr[i], total_bytes - (result ? strlen(result) - 1 : 0)); + safe_strncat(result, arr[i], total_bytes); if (i < (records - 1)) { - strncat(result, separator, total_bytes - strlen(result) - 1); + safe_strncat(result, separator, total_bytes); } } return result; @@ -230,11 +227,11 @@ char *join_ex(char *separator, ...) { result = calloc(size + 1, sizeof(char)); for (size_t i = 0; i < argc; i++) { // Append argument to string - strncat(result, argv[i], size - (result ? strlen(result) - 1 : 0)); // no -1 because +1 above + safe_strncat(result, argv[i], size + 1); // no -1 because +1 above // Do not append a trailing separator when we reach the last argument if (i < (argc - 1)) { - strncat(result, separator, size - strlen(result)); // no -1 because +1 above + safe_strncat(result, separator, size + 1); // no -1 because +1 above } guard_free(argv[i]); } @@ -586,8 +583,7 @@ char *normalize_space(char *s) { // Rewrite the input string const size_t result_len = strlen(result) + 1; - strncpy(result, tmp_orig, result_len); - result[result_len] = '\0'; + safe_strncpy(result, tmp_orig, result_len); guard_free(tmp_orig); return result; @@ -750,3 +746,22 @@ char *remove_extras(char *s) { return s; } +int safe_strncpy(char *dst, const char *src, const size_t dsize) { + return snprintf(dst, dsize, "%s", src); +} + +int safe_strncat(char *dst, const char *src, const size_t dsize) { + const size_t used = strnlen(dst, dsize); + if (used == dsize) { + SYSERROR("destination is not NUL terminated: %p", dst); + return -1; + } + const size_t maxlen = dsize - used; + const int len = snprintf(dst + strlen(dst), maxlen, "%s", src); + if (len < 0) { + SYSERROR("encoding error"); + } else if ((size_t) len >= maxlen) { + SYSWARN("destination truncated: %p", dst); + } + return len; +}
\ No newline at end of file diff --git a/src/lib/core/strlist.c b/src/lib/core/strlist.c index 5cd3f4a..60f3a1f 100644 --- a/src/lib/core/strlist.c +++ b/src/lib/core/strlist.c @@ -88,8 +88,7 @@ int strlist_append_file(struct StrList *pStrList, char *_path, ReaderFn *readerF if (is_url) { int fd; char tempfile[PATH_MAX] = {0}; - strncpy(tempfile, "/tmp/.remote_file.XXXXXX", sizeof(tempfile) - 1); - tempfile[sizeof(tempfile) - 1] = '\0'; + safe_strncpy(tempfile, "/tmp/.remote_file.XXXXXX", sizeof(tempfile)); if ((fd = mkstemp(tempfile)) < 0) { retval = -1; @@ -449,8 +448,7 @@ void strlist_set(struct StrList **pStrList, size_t index, char *value) { const size_t len = strlen(value) + 1; memset((*pStrList)->data[index], '\0', len); - strncpy((*pStrList)->data[index], value, len); - (*pStrList)->data[index][len] = '\0'; + safe_strncpy((*pStrList)->data[index], value, len); } } diff --git a/src/lib/core/system.c b/src/lib/core/system.c index d0956f4..4f1ece6 100644 --- a/src/lib/core/system.c +++ b/src/lib/core/system.c @@ -182,7 +182,7 @@ char *shell_output(const char *command, int *status) { } result = tmp; } - strncat(result, line, current_size - strlen(result) - 1); + safe_strncat(result, line, current_size); memset(line, 0, sizeof(line)); } *status = pclose(pp); diff --git a/src/lib/core/template.c b/src/lib/core/template.c index 8396b1e..fa29104 100644 --- a/src/lib/core/template.c +++ b/src/lib/core/template.c @@ -235,8 +235,7 @@ char *tpl_render(char *str) { value = strdup(env_val ? env_val : ""); } else if (do_func) { // {{ func:NAME(a, ...) }} char func_name_temp[STASIS_NAME_MAX] = {0}; - strncpy(func_name_temp, type_stop + 1, sizeof(func_name_temp) - 1); - func_name_temp[sizeof(func_name_temp) - 1] = '\0'; + safe_strncpy(func_name_temp, type_stop + 1, sizeof(func_name_temp)); char *param_begin = strchr(func_name_temp, '('); if (!param_begin) { @@ -296,7 +295,7 @@ char *tpl_render(char *str) { // Append replacement value grow(z, &output_bytes, &output); - strncat(output, value, output_bytes - strlen(output) - 1); + safe_strncat(output, value, output_bytes); guard_free(value); output[z] = 0; } diff --git a/src/lib/core/template_func_proto.c b/src/lib/core/template_func_proto.c index 54a8860..5cdc441 100644 --- a/src/lib/core/template_func_proto.c +++ b/src/lib/core/template_func_proto.c @@ -80,8 +80,7 @@ int get_junitxml_file_entrypoint(struct tplfunc_frame *frame, void *data_out) { return -1; } char nametmp[PATH_MAX] = {0}; - strncpy(nametmp, cwd, sizeof(nametmp) - 1); - nametmp[sizeof(nametmp) - 1] = '\0'; + safe_strncpy(nametmp, cwd, sizeof(nametmp)); char *name = path_basename(nametmp); @@ -107,8 +106,7 @@ int get_basetemp_dir_entrypoint(struct tplfunc_frame *frame, void *data_out) { return -1; } char nametmp[PATH_MAX] = {0}; - strncpy(nametmp, cwd, sizeof(nametmp) - 1); - nametmp[sizeof(nametmp) - 1] = '\0'; + safe_strncpy(nametmp, cwd, sizeof(nametmp)); char *name = path_basename(nametmp); *output = calloc(PATH_MAX, sizeof(**output)); diff --git a/src/lib/core/utils.c b/src/lib/core/utils.c index d869143..b4a520d 100644 --- a/src/lib/core/utils.c +++ b/src/lib/core/utils.c @@ -37,8 +37,7 @@ int rmtree(char *_path) { char path[PATH_MAX] = {0}; struct dirent *d_entity; - strncpy(path, _path, sizeof(path) - 1); - path[sizeof(path) - 1] = '\0'; + safe_strncpy(path, _path, sizeof(path)); DIR *dir = opendir(path); if (!dir) { @@ -47,9 +46,9 @@ int rmtree(char *_path) { while ((d_entity = readdir(dir)) != NULL) { char abspath[PATH_MAX] = {0}; - strncat(abspath, path, sizeof(abspath) - strlen(abspath) - 1); - strncat(abspath, DIR_SEP, sizeof(abspath) - strlen(abspath) - 1); - strncat(abspath, d_entity->d_name, sizeof(abspath) - strlen(abspath) - 1); + safe_strncat(abspath, path, sizeof(abspath)); + safe_strncat(abspath, DIR_SEP, sizeof(abspath)); + safe_strncat(abspath, d_entity->d_name, sizeof(abspath)); if (!strcmp(d_entity->d_name, ".") || !strcmp(d_entity->d_name, "..") || !strcmp(abspath, path)) { continue; @@ -93,7 +92,7 @@ char *expandpath(const char *_path) { memset(ptmp, '\0', sizeof(tmp)); memset(result, '\0', sizeof(result)); - strncpy(ptmp, _path, PATH_MAX - 1); + safe_strncpy(ptmp, _path, PATH_MAX); // Check whether there's a reason to continue processing the string if (*ptmp != '~') { @@ -107,8 +106,7 @@ char *expandpath(const char *_path) { for (size_t i = 0; i < sizeof(homes) / sizeof(*homes); i++) { char *tmphome; if ((tmphome = getenv(homes[i])) != NULL) { - strncpy(home, tmphome, PATH_MAX - 1); - home[PATH_MAX - 1] = '\0'; + safe_strncpy(home, tmphome, PATH_MAX); break; } } @@ -125,10 +123,10 @@ char *expandpath(const char *_path) { } // Construct the new path - strncat(result, home, sizeof(result) - strlen(home) + 1); + safe_strncat(result, home, sizeof(result)); if (sep) { - strncat(result, DIR_SEP, sizeof(result) - strlen(home) + 1); - strncat(result, ptmp, sizeof(result) - strlen(home) + 1); + safe_strncat(result, DIR_SEP, sizeof(result)); + safe_strncat(result, ptmp, sizeof(result)); } return strdup(result); @@ -280,14 +278,13 @@ char *find_program(const char *name) { result[0] = '\0'; while ((path_elem = strsep(&path, PATH_SEP))) { char abspath[PATH_MAX] = {0}; - strncat(abspath, path_elem, sizeof(abspath) - strlen(abspath) - 1); - strncat(abspath, DIR_SEP, sizeof(abspath) - strlen(abspath) - 1); - strncat(abspath, name, sizeof(abspath) - strlen(abspath) - 1); + safe_strncat(abspath, path_elem, sizeof(abspath)); + safe_strncat(abspath, DIR_SEP, sizeof(abspath)); + safe_strncat(abspath, name, sizeof(abspath)); if (access(abspath, F_OK) < 0) { continue; } - strncpy(result, abspath, sizeof(result) - 1); - result[sizeof(result) - 1] = '\0'; + safe_strncpy(result, abspath, sizeof(result)); break; } path = path_orig; @@ -455,16 +452,15 @@ void msg(unsigned type, char *fmt, ...) { // for error output stream = stderr; fprintf(stream, "%s", STASIS_COLOR_RED); - strncpy(status, " ERROR: ", sizeof(status) - 1); + safe_strncpy(status, " ERROR: ", sizeof(status)); } else if (type & STASIS_MSG_WARN) { stream = stderr; fprintf(stream, "%s", STASIS_COLOR_YELLOW); - strncpy(status, " WARNING: ", sizeof(status) - 1); + safe_strncpy(status, " WARNING: ", sizeof(status)); } else { fprintf(stream, "%s", STASIS_COLOR_GREEN); - strncpy(status, " ", sizeof(status) - 1); + safe_strncpy(status, " ", sizeof(status)); } - status[sizeof(status) - 1] = '\0'; if (type & STASIS_MSG_L1) { snprintf(header, sizeof(header), "==>%s" STASIS_COLOR_RESET STASIS_COLOR_WHITE, status); @@ -507,8 +503,7 @@ char *xmkstemp(FILE **fp, const char *mode) { char tmpdir[PATH_MAX] = {0}; char t_name[PATH_MAX * 2] = {0}; - strncpy(tmpdir, globals.tmpdir ? globals.tmpdir : "/tmp/stasis", sizeof(tmpdir) - 1); - tmpdir[sizeof(tmpdir) - 1] = '\0'; + safe_strncpy(tmpdir, globals.tmpdir ? globals.tmpdir : "/tmp/stasis", sizeof(tmpdir)); if (mkdirs(tmpdir, 0700) < 0) { SYSERROR("unable to create sub-directories in %s", tmpdir); @@ -739,7 +734,7 @@ int fix_tox_conf(const char *filename, char **result, size_t maxlen) { return -1; } value = tmp; - strncat(value, with_posargs, (strlen(value) + strlen(with_posargs)) - strlen(value) - 1); + safe_strncat(value, with_posargs, (strlen(value) + strlen(with_posargs))); ini_setval(&toxini, INI_SETVAL_REPLACE, section_name, key, value); } } @@ -754,7 +749,7 @@ int fix_tox_conf(const char *filename, char **result, size_t maxlen) { fclose(fptemp); // Store path to modified config - strncpy(*result, tempfile, maxlen - 1); + safe_strncpy(*result, tempfile, maxlen); (*result)[maxlen - 1] = '\0'; guard_free(tempfile); @@ -807,8 +802,7 @@ int redact_sensitive(const char **to_redact, size_t to_redact_size, char *src, c if (!tmp) { return -1; } - strncpy(tmp, src, maxlen); - tmp[maxlen] = '\0'; + safe_strncpy(tmp, src, maxlen); for (size_t i = 0; i < to_redact_size; i++) { if (to_redact[i] && strstr(tmp, to_redact[i])) { @@ -818,8 +812,7 @@ int redact_sensitive(const char **to_redact, size_t to_redact_size, char *src, c } memset(dest, 0, maxlen); - strncpy(dest, tmp, maxlen); - dest[maxlen] = '\0'; + safe_strncpy(dest, tmp, maxlen); guard_free(tmp); return 0; @@ -872,16 +865,15 @@ long get_cpu_count() { int mkdirs(const char *_path, mode_t mode) { char *token; char pathbuf[PATH_MAX] = {0}; - strncpy(pathbuf, _path, sizeof(pathbuf) - 1); - pathbuf[sizeof(pathbuf) - 1] = '\0'; + safe_strncpy(pathbuf, _path, sizeof(pathbuf)); char *path = pathbuf; errno = 0; char result[PATH_MAX] = {0}; int status = 0; while ((token = strsep(&path, "/")) != NULL && !status) { - strncat(result, token, sizeof result - strlen(result) - 1); - strncat(result, "/", sizeof result - strlen(result) - 1); + safe_strncat(result, token, sizeof result); + safe_strncat(result, "/", sizeof result); status = mkdir(result, mode); if (status && errno == EEXIST) { status = 0; @@ -946,7 +938,7 @@ int env_manipulate_pathstr(const char *key, char *path, int mode) { int gen_file_extension_str(char *filename, const size_t maxlen, const char *extension) { char *ext_orig = strrchr(filename, '.'); if (!ext_orig) { - strncat(filename, extension, maxlen - strlen(filename) - 1); + safe_strncat(filename, extension, maxlen); return 0; } @@ -974,7 +966,7 @@ void debug_hexdump(char *data, int len) { snprintf(addr + strlen(addr), sizeof(addr) - strlen(addr), "%p", pos); } if (count == 8) { - strncat(bytes, " ", sizeof(bytes) - strlen(bytes) - 1); + safe_strncat(bytes, " ", sizeof(bytes)); } if (count > 15) { snprintf(output, sizeof(output), "%s | %s | %s", addr, bytes, ascii); @@ -996,11 +988,11 @@ void debug_hexdump(char *data, int len) { if (count <= 8) { // Add group padding - strncat(bytes, " ", sizeof(bytes) - strlen(bytes) - 1); + safe_strncat(bytes, " ", sizeof(bytes)); } const int padding = 16 - count; for (int i = 0; i < padding; i++) { - strncat(bytes, " ", sizeof(bytes) - strlen(bytes) - 1); + safe_strncat(bytes, " ", sizeof(bytes)); } snprintf(output, sizeof(output), "%s | %s | %s", addr, bytes, ascii); puts(output); @@ -1276,8 +1268,7 @@ char *center_text(const char *s, const size_t maxwidth) { for (; i < middle; i++) { result[i] = ' '; } - strncpy(&result[i], s, maxwidth - middle - 1); - result[maxwidth] = '\0'; + safe_strncpy(&result[i], s, maxwidth - middle); return result; } diff --git a/src/lib/core/wheel.c b/src/lib/core/wheel.c index e94060a..bb8d106 100644 --- a/src/lib/core/wheel.c +++ b/src/lib/core/wheel.c @@ -1159,8 +1159,7 @@ int wheel_get_entry_point(struct Wheel *pkg, const char *filename) { const size_t start = strcspn((char *) item, "[") + 1; if (start) { const size_t len = strcspn((char *) item, "]"); - strncpy(section, item + start, len - start); - section[len - start] = '\0'; + safe_strncpy(section, item + start, len - start); continue; } } diff --git a/src/lib/core/wheelinfo.c b/src/lib/core/wheelinfo.c index 9d8a6af..fe426aa 100644 --- a/src/lib/core/wheelinfo.c +++ b/src/lib/core/wheelinfo.c @@ -6,8 +6,7 @@ struct WheelInfo *wheelinfo_get(const char *basepath, const char *name, char *to char package_path[PATH_MAX]; char package_name[NAME_MAX]; - strncpy(package_name, name, sizeof(package_name) - 1); - package_name[sizeof(package_name) - 1] = '\0'; + safe_strncpy(package_name, name, sizeof(package_name)); tolower_s(package_name); snprintf(package_path, sizeof(package_path), "%s/%s", basepath, package_name); @@ -22,8 +21,7 @@ struct WheelInfo *wheelinfo_get(const char *basepath, const char *name, char *to } char filename[NAME_MAX]; - strncpy(filename, rec->d_name, sizeof(filename) - 1); - filename[sizeof(filename) - 1] = '\0'; + safe_strncpy(filename, rec->d_name, sizeof(filename)); char *ext = strstr(filename, ".whl"); if (ext) { diff --git a/src/lib/delivery/delivery_build.c b/src/lib/delivery/delivery_build.c index 66f9126..d8674e0 100644 --- a/src/lib/delivery/delivery_build.c +++ b/src/lib/delivery/delivery_build.c @@ -34,15 +34,12 @@ int delivery_build_recipes(struct Delivery *ctx) { const int is_long_tag = num_chars(ctx->tests->test[i]->repository_info_tag, '-') > 1; if (is_long_tag) { const size_t len = strcspn(ctx->tests->test[i]->repository_info_tag, "-"); - strncpy(tag, ctx->tests->test[i]->repository_info_tag, len); - tag[len] = '\0'; + safe_strncpy(tag, ctx->tests->test[i]->repository_info_tag, len); } else { - strncpy(tag, ctx->tests->test[i]->repository_info_tag, sizeof(tag) - 1); - tag[sizeof(tag) - 1] = '\0'; + safe_strncpy(tag, ctx->tests->test[i]->repository_info_tag, sizeof(tag)); } } else { - strncpy(tag, ctx->tests->test[i]->version, sizeof(tag) - 1); - tag[sizeof(tag) - 1] = '\0'; + safe_strncpy(tag, ctx->tests->test[i]->version, sizeof(tag)); } //sprintf(recipe_version, "{%% set version = GIT_DESCRIBE_TAG ~ \".dev\" ~ GIT_DESCRIBE_NUMBER ~ \"+\" ~ GIT_DESCRIBE_HASH %%}"); @@ -55,8 +52,7 @@ int delivery_build_recipes(struct Delivery *ctx) { snprintf(recipe_version, sizeof(recipe_version), "{%% set version = \"%s\" %%}", tag); snprintf(recipe_git_url, sizeof(recipe_git_url), " url: %s/archive/refs/tags/{{ version }}.tar.gz", ctx->tests->test[i]->repository); - strncpy(recipe_git_rev, "", sizeof(recipe_git_rev) - 1); - recipe_git_rev[sizeof(recipe_git_rev) - 1] = '\0'; + safe_strncpy(recipe_git_rev, "", sizeof(recipe_git_rev)); snprintf(recipe_buildno, sizeof(recipe_buildno), " number: 0"); unsigned flags = REPLACE_TRUNCATE_AFTER_MATCH; @@ -80,22 +76,20 @@ int delivery_build_recipes(struct Delivery *ctx) { char arch[STASIS_NAME_MAX] = {0}; char platform[STASIS_NAME_MAX] = {0}; - strncpy(platform, ctx->system.platform[DELIVERY_PLATFORM], sizeof(platform) - 1); + safe_strncpy(platform, ctx->system.platform[DELIVERY_PLATFORM], sizeof(platform)); if (strstr(platform, "Darwin")) { memset(platform, 0, sizeof(platform)); - strncpy(platform, "osx", sizeof(platform) - 1); + safe_strncpy(platform, "osx", sizeof(platform)); } - platform[sizeof(platform) - 1] = '\0'; tolower_s(platform); if (strstr(ctx->system.arch, "arm64")) { - strncpy(arch, "arm64", sizeof(arch) - 1); + safe_strncpy(arch, "arm64", sizeof(arch)); } else if (strstr(ctx->system.arch, "64")) { - strncpy(arch, "64", sizeof(arch) - 1); + safe_strncpy(arch, "64", sizeof(arch)); } else { - strncat(arch, "32", sizeof(arch) - strlen(arch) - 1); // blind guess + safe_strncat(arch, "32", sizeof(arch)); // blind guess } - arch[sizeof(arch) - 1] = '\0'; tolower_s(arch); snprintf(command, sizeof(command), "mambabuild --python=%s -m ../.ci_support/%s_%s_.yaml .", @@ -393,8 +387,7 @@ struct StrList *delivery_build_wheels(struct Delivery *ctx) { for (size_t p = 0; p < strlist_count(ctx->conda.pip_packages_defer); p++) { char name[100] = {0}; char *fullspec = strlist_item(ctx->conda.pip_packages_defer, p); - strncpy(name, fullspec, sizeof(name) - 1); - name[sizeof(name) - 1] = '\0'; + safe_strncpy(name, fullspec, sizeof(name)); remove_extras(name); char *spec = find_version_spec(name); if (spec) { @@ -444,8 +437,7 @@ struct StrList *delivery_build_wheels(struct Delivery *ctx) { COE_CHECK_ABORT(true, "Unreproducible delivery"); } - strncpy(dname, ctx->tests->test[i]->name, sizeof(dname) - 1); - dname[sizeof(dname) - 1] = '\0'; + safe_strncpy(dname, ctx->tests->test[i]->name, sizeof(dname)); tolower_s(dname); snprintf(outdir, sizeof(outdir), "%s/%s", ctx->storage.wheel_artifact_dir, dname); if (mkdirs(outdir, 0755)) { diff --git a/src/lib/delivery/delivery_docker.c b/src/lib/delivery/delivery_docker.c index 79e9729..9b2e1f7 100644 --- a/src/lib/delivery/delivery_docker.c +++ b/src/lib/delivery/delivery_docker.c @@ -44,8 +44,7 @@ int delivery_docker(struct Delivery *ctx) { // Append image tags to command for (size_t i = 0; i < total_tags; i++) { char *tag_orig = strlist_item(ctx->deploy.docker.tags, i); - strncpy(tag, tag_orig, sizeof(tag) - 1); - tag[sizeof(tag) - 1] = '\0'; + safe_strncpy(tag, tag_orig, sizeof(tag)); docker_sanitize_tag(tag); snprintf(args + strlen(args), sizeof(args) - strlen(args), " -t \"%s\" ", tag); } @@ -103,8 +102,7 @@ int delivery_docker(struct Delivery *ctx) { // Test the image // All tags point back to the same image so test the first one we see // regardless of how many are defined - strncpy(tag, strlist_item(ctx->deploy.docker.tags, 0), sizeof(tag) - 1); - tag[sizeof(tag) - 1] = '\0'; + safe_strncpy(tag, strlist_item(ctx->deploy.docker.tags, 0), sizeof(tag)); docker_sanitize_tag(tag); msg(STASIS_MSG_L2, "Executing image test script for %s\n", tag); diff --git a/src/lib/delivery/delivery_init.c b/src/lib/delivery/delivery_init.c index 5bc326d..7cfb9af 100644 --- a/src/lib/delivery/delivery_init.c +++ b/src/lib/delivery/delivery_init.c @@ -217,36 +217,27 @@ int delivery_init_platform(struct Delivery *ctx) { } if (!strcmp(ctx->system.arch, "x86_64")) { - strncpy(archsuffix, "64", sizeof(archsuffix) - 1); + safe_strncpy(archsuffix, "64", sizeof(archsuffix)); } else { - strncpy(archsuffix, ctx->system.arch, sizeof(archsuffix) - 1); + safe_strncpy(archsuffix, ctx->system.arch, sizeof(archsuffix)); } - archsuffix[sizeof(archsuffix) - 1] = '\0'; SYSDEBUG("Setting platform"); - strncpy(ctx->system.platform[DELIVERY_PLATFORM], uts.sysname, DELIVERY_PLATFORM_MAXLEN - 1); - ctx->system.platform[DELIVERY_PLATFORM][DELIVERY_PLATFORM_MAXLEN - 1] = '\0'; + safe_strncpy(ctx->system.platform[DELIVERY_PLATFORM], uts.sysname, DELIVERY_PLATFORM_MAXLEN); if (!strcmp(ctx->system.platform[DELIVERY_PLATFORM], "Darwin")) { snprintf(ctx->system.platform[DELIVERY_PLATFORM_CONDA_SUBDIR], DELIVERY_PLATFORM_MAXLEN, "osx-%s", archsuffix); - strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER], "MacOSX", DELIVERY_PLATFORM_MAXLEN - 1); - ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER][DELIVERY_PLATFORM_MAXLEN - 1] = '\0'; - strncpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], "macos", DELIVERY_PLATFORM_MAXLEN - 1); - ctx->system.platform[DELIVERY_PLATFORM_RELEASE][DELIVERY_PLATFORM_MAXLEN - 1] = '\0'; + safe_strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER], "MacOSX", DELIVERY_PLATFORM_MAXLEN); + safe_strncpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], "macos", DELIVERY_PLATFORM_MAXLEN); } else if (!strcmp(ctx->system.platform[DELIVERY_PLATFORM], "Linux")) { snprintf(ctx->system.platform[DELIVERY_PLATFORM_CONDA_SUBDIR], DELIVERY_PLATFORM_MAXLEN, "linux-%s", archsuffix); - strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER], "Linux", DELIVERY_PLATFORM_MAXLEN - 1); - ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER][DELIVERY_PLATFORM_MAXLEN - 1] = '\0'; - strncpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], "linux", DELIVERY_PLATFORM_MAXLEN - 1); - ctx->system.platform[DELIVERY_PLATFORM_RELEASE][DELIVERY_PLATFORM_MAXLEN - 1] = '\0'; + safe_strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER], "Linux", DELIVERY_PLATFORM_MAXLEN); + safe_strncpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], "linux", DELIVERY_PLATFORM_MAXLEN); } else { // Not explicitly supported systems - strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_SUBDIR], ctx->system.platform[DELIVERY_PLATFORM], DELIVERY_PLATFORM_MAXLEN - 1); - ctx->system.platform[DELIVERY_PLATFORM_CONDA_SUBDIR][DELIVERY_PLATFORM_MAXLEN - 1] = '\0'; - strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER], ctx->system.platform[DELIVERY_PLATFORM], DELIVERY_PLATFORM_MAXLEN - 1); - ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER][DELIVERY_PLATFORM_MAXLEN - 1] = '\0'; - strncpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], ctx->system.platform[DELIVERY_PLATFORM], DELIVERY_PLATFORM_MAXLEN - 1); - ctx->system.platform[DELIVERY_PLATFORM_RELEASE][DELIVERY_PLATFORM_MAXLEN - 1] = '\0'; + safe_strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_SUBDIR], ctx->system.platform[DELIVERY_PLATFORM], DELIVERY_PLATFORM_MAXLEN); + safe_strncpy(ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER], ctx->system.platform[DELIVERY_PLATFORM], DELIVERY_PLATFORM_MAXLEN); + safe_strncpy(ctx->system.platform[DELIVERY_PLATFORM_RELEASE], ctx->system.platform[DELIVERY_PLATFORM], DELIVERY_PLATFORM_MAXLEN); tolower_s(ctx->system.platform[DELIVERY_PLATFORM_RELEASE]); } diff --git a/src/lib/delivery/delivery_install.c b/src/lib/delivery/delivery_install.c index efdb819..bb99014 100644 --- a/src/lib/delivery/delivery_install.c +++ b/src/lib/delivery/delivery_install.c @@ -34,11 +34,9 @@ static char *have_spec_in_config(const struct Delivery *ctx, const char *name) { char *op = find_version_spec(config_spec); char package[255] = {0}; if (op) { - strncpy(package, config_spec, op - config_spec); - package[op - config_spec] = '\0'; + safe_strncpy(package, config_spec, op - config_spec); } else { - strncpy(package, config_spec, sizeof(package) - 1); - package[sizeof(package) - 1] = '\0'; + safe_strncpy(package, config_spec, sizeof(package)); } remove_extras(package); if (strncmp(package, name, strlen(name)) == 0) { @@ -85,11 +83,9 @@ int delivery_overlay_packages_from_env(struct Delivery *ctx, const char *env_nam char spec_name[255] = {0}; char *op = find_version_spec(spec); if (op) { - strncpy(spec_name, spec, op - spec); - spec_name[op - spec] = '\0'; + safe_strncpy(spec_name, spec, op - spec); } else { - strncpy(spec_name, spec, sizeof(spec_name) - 1); - spec_name[sizeof(spec_name) - 1] = '\0'; + safe_strncpy(spec_name, spec, sizeof(spec_name)); } struct Test *test_block = requirement_from_test(ctx, spec_name); @@ -108,11 +104,9 @@ int delivery_overlay_packages_from_env(struct Delivery *ctx, const char *env_nam char *op = find_version_spec(frozen_spec); // we only care about packages with specs here. if something else arrives, ignore it if (op) { - strncpy(frozen_name, frozen_spec, op - frozen_spec); - frozen_name[op - frozen_spec] = '\0'; + safe_strncpy(frozen_name, frozen_spec, op - frozen_spec); } else { - strncpy(frozen_name, frozen_spec, sizeof(frozen_name) - 1); - frozen_name[sizeof(frozen_name) - 1] = '\0'; + safe_strncpy(frozen_name, frozen_spec, sizeof(frozen_name)); } struct Test *test = requirement_from_test(ctx, frozen_name); if (test && strcmp(test->name, frozen_name) == 0) { @@ -307,20 +301,16 @@ int delivery_purge_packages(struct Delivery *ctx, const char *env_name, int use_ case PKG_USE_CONDA: fn = conda_exec; list = ctx->conda.conda_packages_purge; - strncpy(package_manager, "conda", sizeof(package_manager) - 1); - package_manager[sizeof(package_manager) - 1] = '\0'; + safe_strncpy(package_manager, "conda", sizeof(package_manager)); // conda is already configured for "always_yes" - strncpy(subcommand, "remove", sizeof(subcommand) - 1); - subcommand[sizeof(subcommand) - 1] = '\0'; + safe_strncpy(subcommand, "remove", sizeof(subcommand)); break; case PKG_USE_PIP: fn = pip_exec; list = ctx->conda.pip_packages_purge; - strncpy(package_manager, "pip", sizeof(package_manager) - 1); - package_manager[sizeof(package_manager) - 1] = '\0'; + safe_strncpy(package_manager, "pip", sizeof(package_manager)); // avoid user prompt to remove packages - strncpy(subcommand, "uninstall -y", sizeof(subcommand) - 1); - subcommand[sizeof(subcommand) - 1] = '\0'; + safe_strncpy(subcommand, "uninstall -y", sizeof(subcommand)); break; default: SYSERROR("Unknown package manager: %d", use_pkg_manager); @@ -371,7 +361,7 @@ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, cha } memset(command_base, 0, sizeof(command_base)); - strncat(command_base, "install", sizeof(command_base) - strlen(command_base) - 1); + safe_strncat(command_base, "install", sizeof(command_base)); typedef int (*Runner)(const char *); Runner runner = NULL; @@ -387,15 +377,17 @@ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, cha } if (INSTALL_PKG_CONDA_DEFERRED & type) { - strncat(command_base, " --use-local", sizeof(command_base) - strlen(command_base) - 1); - command_base[sizeof(command_base) - 1] = '\0'; + //if (ctx->conda.capabilities.missing_use_local) { + // safe_strncat(command_base, " -c local", sizeof(command_base)); + //} else { + safe_strncat(command_base, " --use-local", sizeof(command_base)); + //} } else if (INSTALL_PKG_PIP_DEFERRED & type) { // Don't change the baseline package set unless we're working with a // new build. Release candidates will need to keep packages as stable // as possible between releases. if (!ctx->meta.based_on) { - strncat(command_base, " --upgrade", sizeof(command_base) - strlen(command_base) - 1); - command_base[sizeof(command_base) - 1] = '\0'; + safe_strncat(command_base, " --upgrade", sizeof(command_base)); } snprintf(command_base + strlen(command_base), sizeof(command_base) - strlen(command_base), " --extra-index-url 'file://%s'", ctx->storage.wheel_artifact_dir); } @@ -470,11 +462,9 @@ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, cha char req[255] = {0}; if (!strcmp(name, info->name)) { - strncpy(req, info->name, sizeof(req) - 1); - req[sizeof(req) - 1] = '\0'; + safe_strncpy(req, info->name, sizeof(req)); } else { - strncpy(req, name, sizeof(req) - 1); - req[sizeof(req) - 1] = '\0'; + safe_strncpy(req, name, sizeof(req)); char *spec = find_version_spec(req); if (spec) { *spec = 0; diff --git a/src/lib/delivery/delivery_test.c b/src/lib/delivery/delivery_test.c index f59a62e..c1ef1ad 100644 --- a/src/lib/delivery/delivery_test.c +++ b/src/lib/delivery/delivery_test.c @@ -199,13 +199,11 @@ void delivery_tests_run(struct Delivery *ctx) { msg(STASIS_MSG_L3, "Queuing task for %s\n", test->name); memset(&proc, 0, sizeof(proc)); - strncpy(cmd, test->script, strlen(test->script) + STASIS_BUFSIZ - 1); - cmd[strlen(test->script) + STASIS_BUFSIZ - 1] = '\0'; + safe_strncpy(cmd, test->script, strlen(test->script) + STASIS_BUFSIZ); char *cmd_rendered = tpl_render(cmd); if (cmd_rendered) { if (strcmp(cmd_rendered, cmd) != 0) { - strncpy(cmd, cmd_rendered, strlen(test->script) + STASIS_BUFSIZ - 1); - cmd[strlen(cmd_rendered) ? strlen(cmd_rendered) - 1 : 0] = 0; + safe_strncpy(cmd, cmd_rendered, strlen(test->script) + STASIS_BUFSIZ); } guard_free(cmd_rendered); } else { @@ -229,8 +227,7 @@ void delivery_tests_run(struct Delivery *ctx) { if (!globals.enable_parallel || !test->parallel) { selected = SERIAL; memset(pool_name, 0, sizeof(pool_name)); - strncpy(pool_name, "serial", sizeof(pool_name) - 1); - pool_name[sizeof(pool_name) - 1] = '\0'; + safe_strncpy(pool_name, "serial", sizeof(pool_name)); } if (asprintf(&runner_cmd, runner_cmd_fmt, cmd) < 0) { @@ -281,14 +278,12 @@ void delivery_tests_run(struct Delivery *ctx) { exit(1); } - strncpy(cmd, test->script_setup, cmd_len - 1); - cmd[cmd_len - 1] = '\0'; + safe_strncpy(cmd, test->script_setup, cmd_len); char *cmd_rendered = tpl_render(cmd); if (cmd_rendered) { if (strcmp(cmd_rendered, cmd) != 0) { - strncpy(cmd, cmd_rendered, cmd_len - 1); - cmd[strlen(cmd_rendered) ? strlen(cmd_rendered) - 1 : 0] = '\0'; + safe_strncpy(cmd, cmd_rendered, cmd_len); } guard_free(cmd_rendered); } else { |
