aboutsummaryrefslogtreecommitdiff
path: root/src/lib/delivery
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@users.noreply.github.com>2026-04-28 11:45:10 -0400
committerGitHub <noreply@github.com>2026-04-28 11:45:10 -0400
commit10f13b36560c5112554c54d8958081b7aa518050 (patch)
treebd27866c4352de38ebc5b13f8208768d576ae904 /src/lib/delivery
parent017bc273aedf3f20512beeb78a2f513913e56305 (diff)
parentd761cc976a8d645e61d23f6e43dcfec1a7fdb061 (diff)
downloadstasis-10f13b36560c5112554c54d8958081b7aa518050.tar.gz
Merge pull request #137 from jhunkeler/bughunt-1001
Bug Hunt 0x1001
Diffstat (limited to 'src/lib/delivery')
-rw-r--r--src/lib/delivery/delivery.c20
-rw-r--r--src/lib/delivery/delivery_build.c11
-rw-r--r--src/lib/delivery/delivery_docker.c2
-rw-r--r--src/lib/delivery/delivery_export.c18
-rw-r--r--src/lib/delivery/delivery_init.c62
-rw-r--r--src/lib/delivery/delivery_install.c12
-rw-r--r--src/lib/delivery/delivery_postprocess.c1
-rw-r--r--src/lib/delivery/delivery_test.c6
8 files changed, 111 insertions, 21 deletions
diff --git a/src/lib/delivery/delivery.c b/src/lib/delivery/delivery.c
index 5403743..45b3b35 100644
--- a/src/lib/delivery/delivery.c
+++ b/src/lib/delivery/delivery.c
@@ -312,13 +312,13 @@ int delivery_format_str(struct Delivery *ctx, char **dest, size_t maxlen, const
strncat(*dest, ctx->meta.mission, maxlen - 1);
break;
case 'r': // revision
- snprintf(*dest + strlen(*dest), maxlen, "%d", ctx->meta.rc);
+ snprintf(*dest + strlen(*dest), maxlen - strlen(*dest), "%d", ctx->meta.rc);
break;
case 'R': // "final"-aware revision
if (ctx->meta.final)
strncat(*dest, "final", maxlen);
else
- snprintf(*dest + strlen(*dest), maxlen, "%d", ctx->meta.rc);
+ snprintf(*dest + strlen(*dest), maxlen - strlen(*dest), "%d", ctx->meta.rc);
break;
case 'v': // version
strncat(*dest, ctx->meta.version, maxlen - 1);
@@ -336,14 +336,14 @@ int delivery_format_str(struct Delivery *ctx, char **dest, size_t maxlen, const
strncat(*dest, ctx->system.platform[DELIVERY_PLATFORM_RELEASE], maxlen - 1);
break;
case 't': // unix epoch
- snprintf(*dest + strlen(*dest), maxlen, "%ld", ctx->info.time_now);
+ snprintf(*dest + strlen(*dest), maxlen - strlen(*dest), "%ld", ctx->info.time_now);
break;
default: // unknown formatter, write as-is
- snprintf(*dest + strlen(*dest), maxlen, "%c%c", fmt[i - 1], fmt[i]);
+ snprintf(*dest + strlen(*dest), maxlen - strlen(*dest), "%c%c", fmt[i - 1], fmt[i]);
break;
}
} else { // write non-format text
- snprintf(*dest + strlen(*dest), maxlen, "%c", fmt[i]);
+ snprintf(*dest + strlen(*dest), maxlen - strlen(*dest), "%c", fmt[i]);
}
}
return 0;
@@ -367,6 +367,8 @@ void delivery_defer_packages(struct Delivery *ctx, int type) {
SYSERROR("BUG: type %d does not map to a supported package manager!\n", type);
exit(1);
}
+ mode[sizeof(mode) - 1] = '\0';
+
msg(STASIS_MSG_L2, "Filtering %s packages by test definition...\n", mode);
struct StrList *filtered = NULL;
@@ -391,8 +393,10 @@ void delivery_defer_packages(struct Delivery *ctx, int type) {
spec_end++;
}
strncpy(package_name, name, spec_begin - name);
+ package_name[spec_begin - name] = '\0';
} else {
strncpy(package_name, name, sizeof(package_name) - 1);
+ package_name[sizeof(package_name) - 1] = '\0';
}
remove_extras(package_name);
@@ -404,6 +408,8 @@ void delivery_defer_packages(struct Delivery *ctx, int type) {
char nametmp[STASIS_NAME_MAX] = {0};
strncpy(nametmp, package_name, sizeof(nametmp) - 1);
+ nametmp[sizeof(nametmp) - 1] = '\0';
+
// Is the [test:NAME] in the package name?
if (!strcmp(nametmp, test->name)) {
// Override test->version when a version is provided by the (pip|conda)_package list item
@@ -447,9 +453,9 @@ void delivery_defer_packages(struct Delivery *ctx, int type) {
int upstream_exists = 0;
if (DEFER_PIP == type) {
- upstream_exists = pkg_index_provides(PKG_USE_PIP, PYPI_INDEX_DEFAULT, name);
+ upstream_exists = pkg_index_provides(PKG_USE_PIP, PYPI_INDEX_DEFAULT, name, ctx->storage.tmpdir);
} else if (DEFER_CONDA == type) {
- upstream_exists = pkg_index_provides(PKG_USE_CONDA, NULL, name);
+ upstream_exists = pkg_index_provides(PKG_USE_CONDA, NULL, name, ctx->storage.tmpdir);
}
if (PKG_INDEX_PROVIDES_FAILED(upstream_exists)) {
diff --git a/src/lib/delivery/delivery_build.c b/src/lib/delivery/delivery_build.c
index 3ff5df7..49d2f5b 100644
--- a/src/lib/delivery/delivery_build.c
+++ b/src/lib/delivery/delivery_build.c
@@ -34,10 +34,11 @@ int delivery_build_recipes(struct Delivery *ctx) {
tag[len] = '\0';
} else {
strncpy(tag, ctx->tests->test[i]->repository_info_tag, sizeof(tag) - 1);
- tag[strlen(ctx->tests->test[i]->repository_info_tag)] = '\0';
+ tag[sizeof(tag) - 1] = '\0';
}
} else {
strncpy(tag, ctx->tests->test[i]->version, sizeof(tag) - 1);
+ tag[sizeof(tag) - 1] = '\0';
}
//sprintf(recipe_version, "{%% set version = GIT_DESCRIBE_TAG ~ \".dev\" ~ GIT_DESCRIBE_NUMBER ~ \"+\" ~ GIT_DESCRIBE_HASH %%}");
@@ -51,6 +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';
snprintf(recipe_buildno, sizeof(recipe_buildno), " number: 0");
unsigned flags = REPLACE_TRUNCATE_AFTER_MATCH;
@@ -79,14 +81,17 @@ int delivery_build_recipes(struct Delivery *ctx) {
memset(platform, 0, sizeof(platform));
strncpy(platform, "osx", sizeof(platform) - 1);
}
+ platform[sizeof(platform) - 1] = '\0';
tolower_s(platform);
+
if (strstr(ctx->system.arch, "arm64")) {
strncpy(arch, "arm64", sizeof(arch) - 1);
} else if (strstr(ctx->system.arch, "64")) {
strncpy(arch, "64", sizeof(arch) - 1);
} else {
- strncat(arch, "32", sizeof(arch) - 1); // blind guess
+ strncat(arch, "32", sizeof(arch) - strlen(arch) - 1); // blind guess
}
+ arch[sizeof(arch) - 1] = '\0';
tolower_s(arch);
snprintf(command, sizeof(command), "mambabuild --python=%s -m ../.ci_support/%s_%s_.yaml .",
@@ -385,6 +390,7 @@ struct StrList *delivery_build_wheels(struct Delivery *ctx) {
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';
remove_extras(name);
char *spec = find_version_spec(name);
if (spec) {
@@ -435,6 +441,7 @@ struct StrList *delivery_build_wheels(struct Delivery *ctx) {
}
strncpy(dname, ctx->tests->test[i]->name, sizeof(dname) - 1);
+ dname[sizeof(dname) - 1] = '\0';
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 1178a8c..3177c96 100644
--- a/src/lib/delivery/delivery_docker.c
+++ b/src/lib/delivery/delivery_docker.c
@@ -45,6 +45,7 @@ int delivery_docker(struct Delivery *ctx) {
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';
docker_sanitize_tag(tag);
snprintf(args + strlen(args), sizeof(args) - strlen(args), " -t \"%s\" ", tag);
}
@@ -103,6 +104,7 @@ int delivery_docker(struct Delivery *ctx) {
// 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';
docker_sanitize_tag(tag);
msg(STASIS_MSG_L2, "Executing image test script for %s\n", tag);
diff --git a/src/lib/delivery/delivery_export.c b/src/lib/delivery/delivery_export.c
index c12a365..e67fdfb 100644
--- a/src/lib/delivery/delivery_export.c
+++ b/src/lib/delivery/delivery_export.c
@@ -2,26 +2,44 @@
static void delivery_export_configuration(const struct Delivery *ctx) {
msg(STASIS_MSG_L2, "Exporting delivery configuration\n");
+
+ SYSDEBUG("Entering configuration directory: %s", ctx->storage.delivery_dir);
if (!pushd(ctx->storage.cfgdump_dir)) {
char filename[PATH_MAX] = {0};
+ SYSDEBUG("%s", "Populating filename");
snprintf(filename, sizeof(filename), "%s.ini", ctx->info.release_name);
+ SYSDEBUG("filename: %s", filename);
+
+ SYSDEBUG("%s: opening", filename);
FILE *spec = fopen(filename, "w+");
if (!spec) {
msg(STASIS_MSG_ERROR | STASIS_MSG_L2, "failed %s\n", filename);
exit(1);
}
+ SYSDEBUG("%s: writing", filename);
ini_write(ctx->_stasis_ini_fp.delivery, &spec, INI_WRITE_RAW);
+ SYSDEBUG("%s: writing done", filename);
fclose(spec);
+ SYSDEBUG("%s: closing", filename);
+ SYSDEBUG("%s", "Zeroing filename");
memset(filename, 0, sizeof(filename));
+ SYSDEBUG("%s", "Populating rendered filename");
snprintf(filename, sizeof(filename), "%s-rendered.ini", ctx->info.release_name);
+ SYSDEBUG("filename: %s", filename);
+
+ SYSDEBUG("%s: opening", filename);
spec = fopen(filename, "w+");
if (!spec) {
msg(STASIS_MSG_ERROR | STASIS_MSG_L2, "failed %s\n", filename);
exit(1);
}
+ SYSDEBUG("%s: writing", filename);
ini_write(ctx->_stasis_ini_fp.delivery, &spec, INI_WRITE_PRESERVE);
+ SYSDEBUG("%s: writing done", filename);
+ SYSDEBUG("%s: closing", filename);
fclose(spec);
+ SYSDEBUG("Returning from %s", ctx->storage.cfgdump_dir);
popd();
} else {
SYSERROR("Failed to enter directory: %s", ctx->storage.delivery_dir);
diff --git a/src/lib/delivery/delivery_init.c b/src/lib/delivery/delivery_init.c
index ff877f0..ec05a0f 100644
--- a/src/lib/delivery/delivery_init.c
+++ b/src/lib/delivery/delivery_init.c
@@ -11,23 +11,43 @@ int has_mount_flags(const char *mount_point, const unsigned long flags) {
int delivery_init_tmpdir(struct Delivery *ctx) {
char *tmpdir = NULL;
- char *x = NULL;
- int unusable = 0;
+ int unusable = 1;
errno = 0;
- x = getenv("TMPDIR");
+ //int need_setenv = 0;
+ const char *x = getenv("TMPDIR");
if (x) {
guard_free(ctx->storage.tmpdir);
tmpdir = strdup(x);
+ if (!tmpdir) {
+ // memory error
+ SYSERROR("%s", "unable to allocate tmpdir");
+ goto l_delivery_init_tmpdir_fatal;
+ }
} else {
- tmpdir = ctx->storage.tmpdir;
+ tmpdir = strdup("/tmp/stasis");
+ if (!tmpdir) {
+ SYSERROR("%s", "unable to allocate tmpdir");
+ goto l_delivery_init_tmpdir_fatal;
+ }
+ //need_setenv = 1;
}
- if (!tmpdir) {
- // memory error
- return -1;
+ if (!ctx->storage.tmpdir) {
+ ctx->storage.tmpdir = strdup(tmpdir);
+ if (!ctx->storage.tmpdir) {
+ SYSERROR("%s", "unable to allocate ctx->storage.tmpdir");
+ goto l_delivery_init_tmpdir_fatal;
+ }
+ } else {
+ // we already have a temp directory to use
+ guard_free(tmpdir);
+ tmpdir = strdup(ctx->storage.tmpdir);
+ if (!tmpdir) {
+ SYSERROR("%s", "unable to allocate tmpdir");
+ goto l_delivery_init_tmpdir_fatal;
+ }
}
-
// If the directory doesn't exist, create it
if (access(tmpdir, F_OK) < 0) {
if (mkdirs(tmpdir, 0755) < 0) {
@@ -59,17 +79,29 @@ int delivery_init_tmpdir(struct Delivery *ctx) {
goto l_delivery_init_tmpdir_fatal;
}
- if (!globals.tmpdir) {
+ if (!globals.tmpdir || strcmp(globals.tmpdir, ctx->storage.tmpdir) != 0) {
globals.tmpdir = strdup(tmpdir);
+ if (!globals.tmpdir) {
+ SYSERROR("%s", "unable to allocate globals.tmpdir");
+ goto l_delivery_init_tmpdir_fatal;
+ }
}
if (!ctx->storage.tmpdir) {
ctx->storage.tmpdir = strdup(globals.tmpdir);
+ if (!ctx->storage.tmpdir) {
+ SYSERROR("%s", "unable to allocate globals.tmpdir");
+ goto l_delivery_init_tmpdir_fatal;
+ }
}
- return unusable;
+ unusable = 0;
+ // TODO: Figure out why this breaks EVERYTHING
+ //if (need_setenv) {
+ // setenv("TMPDIR", ctx->storage.tmpdir, 1);
+ //}
l_delivery_init_tmpdir_fatal:
- unusable = 1;
+ guard_free(tmpdir);
return unusable;
}
@@ -178,22 +210,30 @@ int delivery_init_platform(struct Delivery *ctx) {
} else {
strncpy(archsuffix, ctx->system.arch, sizeof(archsuffix) - 1);
}
+ archsuffix[sizeof(archsuffix) - 1] = '\0';
SYSDEBUG("%s", "Setting platform");
strncpy(ctx->system.platform[DELIVERY_PLATFORM], uts.sysname, DELIVERY_PLATFORM_MAXLEN - 1);
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';
} 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';
} 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';
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 22b3752..3d54eaa 100644
--- a/src/lib/delivery/delivery_install.c
+++ b/src/lib/delivery/delivery_install.c
@@ -32,8 +32,10 @@ static char *have_spec_in_config(const struct Delivery *ctx, const char *name) {
char package[255] = {0};
if (op) {
strncpy(package, config_spec, op - config_spec);
+ package[op - config_spec] = '\0';
} else {
strncpy(package, config_spec, sizeof(package) - 1);
+ package[sizeof(package) - 1] = '\0';
}
remove_extras(package);
if (strncmp(package, name, strlen(name)) == 0) {
@@ -81,8 +83,10 @@ int delivery_overlay_packages_from_env(struct Delivery *ctx, const char *env_nam
char *op = find_version_spec(spec);
if (op) {
strncpy(spec_name, spec, op - spec);
+ spec_name[op - spec] = '\0';
} else {
strncpy(spec_name, spec, sizeof(spec_name) - 1);
+ spec_name[sizeof(spec_name) - 1] = '\0';
}
struct Test *test_block = requirement_from_test(ctx, spec_name);
@@ -102,8 +106,10 @@ int delivery_overlay_packages_from_env(struct Delivery *ctx, const char *env_nam
// 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';
} else {
strncpy(frozen_name, frozen_spec, sizeof(frozen_name) - 1);
+ frozen_name[sizeof(frozen_name) - 1] = '\0';
}
struct Test *test = requirement_from_test(ctx, frozen_name);
if (test && strcmp(test->name, frozen_name) == 0) {
@@ -151,15 +157,19 @@ int delivery_purge_packages(struct Delivery *ctx, const char *env_name, int use_
fn = conda_exec;
list = ctx->conda.conda_packages_purge;
strncpy(package_manager, "conda", sizeof(package_manager) - 1);
+ package_manager[sizeof(package_manager) - 1] = '\0';
// conda is already configured for "always_yes"
strncpy(subcommand, "remove", sizeof(subcommand) - 1);
+ subcommand[sizeof(subcommand) - 1] = '\0';
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';
// avoid user prompt to remove packages
strncpy(subcommand, "uninstall -y", sizeof(subcommand) - 1);
+ subcommand[sizeof(subcommand) - 1] = '\0';
break;
default:
SYSERROR("Unknown package manager: %d", use_pkg_manager);
@@ -300,8 +310,10 @@ 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';
} else {
strncpy(req, name, sizeof(req) - 1);
+ req[sizeof(req) - 1] = '\0';
char *spec = find_version_spec(req);
if (spec) {
*spec = 0;
diff --git a/src/lib/delivery/delivery_postprocess.c b/src/lib/delivery/delivery_postprocess.c
index 95bcc0a..3ff1d56 100644
--- a/src/lib/delivery/delivery_postprocess.c
+++ b/src/lib/delivery/delivery_postprocess.c
@@ -243,6 +243,7 @@ int delivery_index_wheel_artifacts(struct Delivery *ctx) {
FILE *bottom_fp = fopen(bottom_index, "w+");
if (!bottom_fp) {
closedir(dp);
+ fclose(top_fp);
return -3;
}
diff --git a/src/lib/delivery/delivery_test.c b/src/lib/delivery/delivery_test.c
index a088cd7..5d5a3e8 100644
--- a/src/lib/delivery/delivery_test.c
+++ b/src/lib/delivery/delivery_test.c
@@ -201,6 +201,7 @@ void delivery_tests_run(struct Delivery *ctx) {
memset(&proc, 0, sizeof(proc));
strncpy(cmd, test->script, strlen(test->script) + STASIS_BUFSIZ - 1);
+ cmd[strlen(test->script) + STASIS_BUFSIZ - 1] = '\0';
char *cmd_rendered = tpl_render(cmd);
if (cmd_rendered) {
if (strcmp(cmd_rendered, cmd) != 0) {
@@ -230,6 +231,7 @@ void delivery_tests_run(struct Delivery *ctx) {
selected = SERIAL;
memset(pool_name, 0, sizeof(pool_name));
strncpy(pool_name, "serial", sizeof(pool_name) - 1);
+ pool_name[sizeof(pool_name) - 1] = '\0';
}
if (asprintf(&runner_cmd, runner_cmd_fmt, cmd) < 0) {
@@ -281,11 +283,13 @@ void delivery_tests_run(struct Delivery *ctx) {
}
strncpy(cmd, test->script_setup, cmd_len - 1);
+ cmd[cmd_len - 1] = '\0';
+
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;
+ cmd[strlen(cmd_rendered) ? strlen(cmd_rendered) - 1 : 0] = '\0';
}
guard_free(cmd_rendered);
} else {