aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@users.noreply.github.com>2025-11-10 14:41:21 -0500
committerGitHub <noreply@github.com>2025-11-10 14:41:21 -0500
commitcf50be9ef96fd8011fbd45321b4c454470112cf4 (patch)
treed0586dd5cfc703586752dfc318a068a31539850a /src/lib
parentd90493618ce34a732c5411d1670be57d4dd9db4e (diff)
parentb999413700231b5d922c91addef7c080fd289b30 (diff)
downloadstasis-cf50be9ef96fd8011fbd45321b4c454470112cf4.tar.gz
Merge pull request #119 from jhunkeler/indexer-buffer-overlow
Indexer buffer overflow and leak(s)
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/core/envctl.c3
-rw-r--r--src/lib/core/multiprocessing.c1
-rw-r--r--src/lib/delivery/delivery.c173
-rw-r--r--src/lib/delivery/include/delivery.h13
4 files changed, 186 insertions, 4 deletions
diff --git a/src/lib/core/envctl.c b/src/lib/core/envctl.c
index 0be3f89..b036611 100644
--- a/src/lib/core/envctl.c
+++ b/src/lib/core/envctl.c
@@ -17,6 +17,8 @@ struct EnvCtl *envctl_init() {
}
static int callback_builtin_nop(const void *a, const void *b) {
+ (void) a; // Unused
+ (void) b; // Unused
return STASIS_ENVCTL_RET_SUCCESS;
}
@@ -58,6 +60,7 @@ size_t envctl_get_index(const struct EnvCtl *envctl, const char *name) {
}
void envctl_decode_index(size_t in_i, size_t *state, size_t *out_i, size_t *name_i) {
+ (void) name_i;
*state = ((in_i >> 63L) & 1);
*out_i = in_i & 0xffffffffL;
}
diff --git a/src/lib/core/multiprocessing.c b/src/lib/core/multiprocessing.c
index 0cf251e..d59a7cd 100644
--- a/src/lib/core/multiprocessing.c
+++ b/src/lib/core/multiprocessing.c
@@ -9,6 +9,7 @@ static struct MultiProcessingTask *mp_pool_next_available(struct MultiProcessing
}
int child(struct MultiProcessingPool *pool, struct MultiProcessingTask *task) {
+ (void) pool;
FILE *fp_log = NULL;
// The task starts inside the requested working directory
diff --git a/src/lib/delivery/delivery.c b/src/lib/delivery/delivery.c
index 7ec2e04..600ddf9 100644
--- a/src/lib/delivery/delivery.c
+++ b/src/lib/delivery/delivery.c
@@ -1,5 +1,178 @@
#include "delivery.h"
+static char *strdup_maybe(const char * restrict s) {
+ if (s != NULL) {
+ return strdup(s);
+ }
+ return NULL;
+}
+struct Delivery *delivery_duplicate(const struct Delivery *ctx) {
+ struct Delivery *result = calloc(1, sizeof(*result));
+ if (!result) {
+ return NULL;
+ }
+ // Conda
+ result->conda.conda_packages = strlist_copy(ctx->conda.conda_packages);
+ result->conda.conda_packages_defer = strlist_copy(ctx->conda.conda_packages_defer);
+ result->conda.conda_packages_purge = strlist_copy(ctx->conda.conda_packages_purge);
+ result->conda.pip_packages = strlist_copy(ctx->conda.pip_packages);
+ result->conda.pip_packages_defer = strlist_copy(ctx->conda.pip_packages_defer);
+ result->conda.pip_packages_purge = strlist_copy(ctx->conda.pip_packages_purge);
+ result->conda.wheels_packages = strlist_copy(ctx->conda.wheels_packages);
+ result->conda.installer_arch = strdup_maybe(ctx->conda.installer_arch);
+ result->conda.installer_baseurl = strdup_maybe(ctx->conda.installer_baseurl);
+ result->conda.installer_name = strdup_maybe(ctx->conda.installer_name);
+ result->conda.installer_path = strdup_maybe(ctx->conda.installer_path);
+ result->conda.installer_platform = strdup_maybe(ctx->conda.installer_platform);
+ result->conda.installer_version = strdup_maybe(ctx->conda.installer_version);
+ result->conda.tool_build_version = strdup_maybe(ctx->conda.tool_build_version);
+ result->conda.tool_version = strdup_maybe(ctx->conda.tool_version);
+
+ // Info
+ result->info.build_name = strdup_maybe(ctx->info.build_name);
+ result->info.build_number = strdup_maybe(ctx->info.build_number);
+ result->info.release_name = strdup_maybe(ctx->info.release_name);
+ result->info.time_info = ctx->info.time_info;
+ result->info.time_now = ctx->info.time_now;
+ result->info.time_str_epoch = strdup_maybe(ctx->info.time_str_epoch);
+
+ // Meta
+ result->meta.name = strdup_maybe(ctx->meta.name);
+ result->meta.based_on = strdup_maybe(ctx->meta.based_on);
+ result->meta.codename = strdup_maybe(ctx->meta.codename);
+ result->meta.mission = strdup_maybe(ctx->meta.mission);
+ result->meta.final = ctx->meta.final;
+ result->meta.python = strdup_maybe(ctx->meta.python);
+ result->meta.python_compact = strdup_maybe(ctx->meta.python_compact);
+ result->meta.rc = ctx->meta.rc;
+ result->meta.version = strdup_maybe(ctx->meta.version);
+
+ // Rules
+ result->rules.build_name_fmt = strdup_maybe(ctx->rules.build_name_fmt);
+ result->rules.build_number_fmt = strdup_maybe(ctx->rules.build_number_fmt);
+ // Unused member?
+ result->rules.enable_final = ctx->rules.enable_final;
+ result->rules.release_fmt = ctx->rules.release_fmt;
+ // TODO: need content duplication function
+ memcpy(&result->rules.content, &ctx->rules.content, sizeof(ctx->rules.content));
+
+ if (ctx->rules._handle) {
+ result->rules._handle = malloc(sizeof(*result->rules._handle));
+ result->rules._handle->section = malloc(result->rules._handle->section_count * sizeof(*result->rules._handle->section));
+ memcpy(result->rules._handle, &ctx->rules._handle, sizeof(*ctx->rules._handle));
+ }
+
+ // Runtime
+ if (ctx->runtime.environ) {
+ result->runtime.environ = runtime_copy(ctx->runtime.environ->data);
+ }
+
+ // Storage
+ result->storage.tools_dir = strdup_maybe(ctx->storage.tools_dir);
+ result->storage.package_dir = strdup_maybe(ctx->storage.package_dir);
+ result->storage.results_dir = strdup_maybe(ctx->storage.results_dir);
+ result->storage.output_dir = strdup_maybe(ctx->storage.output_dir);
+ result->storage.cfgdump_dir = strdup_maybe(ctx->storage.cfgdump_dir);
+ result->storage.delivery_dir = strdup_maybe(ctx->storage.delivery_dir);
+ result->storage.meta_dir = strdup_maybe(ctx->storage.meta_dir);
+ result->storage.mission_dir = strdup_maybe(ctx->storage.mission_dir);
+ result->storage.root = strdup_maybe(ctx->storage.root);
+ result->storage.tmpdir = strdup_maybe(ctx->storage.tmpdir);
+ result->storage.build_dir = strdup_maybe(ctx->storage.build_dir);
+ result->storage.build_docker_dir = strdup_maybe(ctx->storage.build_docker_dir);
+ result->storage.build_recipes_dir = strdup_maybe(ctx->storage.build_recipes_dir);
+ result->storage.build_sources_dir = strdup_maybe(ctx->storage.build_sources_dir);
+ result->storage.build_testing_dir = strdup_maybe(ctx->storage.build_testing_dir);
+ result->storage.conda_artifact_dir = strdup_maybe(ctx->storage.conda_artifact_dir);
+ result->storage.conda_install_prefix = strdup_maybe(ctx->storage.conda_install_prefix);
+ result->storage.conda_staging_dir = strdup_maybe(ctx->storage.conda_staging_dir);
+ result->storage.conda_staging_url = strdup_maybe(ctx->storage.conda_staging_url);
+ result->storage.docker_artifact_dir = strdup_maybe(ctx->storage.docker_artifact_dir);
+ result->storage.wheel_artifact_dir = strdup_maybe(ctx->storage.wheel_artifact_dir);
+ result->storage.wheel_staging_url = strdup_maybe(ctx->storage.wheel_staging_url);
+
+ result->system.arch = strdup_maybe(ctx->system.arch);
+ if (ctx->system.platform) {
+ result->system.platform = malloc(DELIVERY_PLATFORM_MAX * sizeof(*result->system.platform));
+ for (size_t i = 0; i < DELIVERY_PLATFORM_MAX; i++) {
+ result->system.platform[i] = strdup_maybe(ctx->system.platform[i]);
+ }
+ }
+
+ // Docker
+ result->deploy.docker.build_args = strlist_copy(ctx->deploy.docker.build_args);
+ result->deploy.docker.tags = strlist_copy(ctx->deploy.docker.tags);
+ result->deploy.docker.capabilities = ctx->deploy.docker.capabilities;
+ result->deploy.docker.dockerfile = strdup_maybe(ctx->deploy.docker.dockerfile);
+ result->deploy.docker.image_compression = strdup_maybe(ctx->deploy.docker.image_compression);
+ result->deploy.docker.registry = strdup_maybe(ctx->deploy.docker.registry);
+ result->deploy.docker.test_script = strdup_maybe(ctx->deploy.docker.test_script);
+
+ // Jfrog
+ // TODO: break out into a separate a function
+ for (size_t i = 0; i < sizeof(ctx->deploy.jfrog) / sizeof(ctx->deploy.jfrog[0]); i++) {
+ result->deploy.jfrog[i].dest = strdup_maybe(ctx->deploy.jfrog[i].dest);
+ result->deploy.jfrog[i].files = strlist_copy(ctx->deploy.jfrog[i].files);
+ result->deploy.jfrog[i].repo = strdup_maybe(ctx->deploy.jfrog[i].repo);
+ result->deploy.jfrog[i].upload_ctx.ant = ctx->deploy.jfrog[i].upload_ctx.ant;
+ result->deploy.jfrog[i].upload_ctx.archive = ctx->deploy.jfrog[i].upload_ctx.archive;
+ result->deploy.jfrog[i].upload_ctx.build_name = ctx->deploy.jfrog[i].upload_ctx.build_name;
+ result->deploy.jfrog[i].upload_ctx.build_number = ctx->deploy.jfrog[i].upload_ctx.build_number;
+ result->deploy.jfrog[i].upload_ctx.deb = ctx->deploy.jfrog[i].upload_ctx.deb;
+ result->deploy.jfrog[i].upload_ctx.detailed_summary = ctx->deploy.jfrog[i].upload_ctx.detailed_summary;
+ result->deploy.jfrog[i].upload_ctx.dry_run = ctx->deploy.jfrog[i].upload_ctx.dry_run;
+ result->deploy.jfrog[i].upload_ctx.exclusions = strdup_maybe(ctx->deploy.jfrog[i].upload_ctx.exclusions);
+ result->deploy.jfrog[i].upload_ctx.explode = ctx->deploy.jfrog[i].upload_ctx.explode;
+ result->deploy.jfrog[i].upload_ctx.fail_no_op = ctx->deploy.jfrog[i].upload_ctx.fail_no_op;
+ result->deploy.jfrog[i].upload_ctx.flat = ctx->deploy.jfrog[i].upload_ctx.flat;
+ result->deploy.jfrog[i].upload_ctx.include_dirs = ctx->deploy.jfrog[i].upload_ctx.include_dirs;
+ result->deploy.jfrog[i].upload_ctx.module = strdup_maybe(ctx->deploy.jfrog[i].upload_ctx.module);
+ result->deploy.jfrog[i].upload_ctx.project = strdup_maybe(ctx->deploy.jfrog[i].upload_ctx.project);
+ result->deploy.jfrog[i].upload_ctx.quiet = ctx->deploy.jfrog[i].upload_ctx.quiet;
+ result->deploy.jfrog[i].upload_ctx.recursive = ctx->deploy.jfrog[i].upload_ctx.recursive;
+ result->deploy.jfrog[i].upload_ctx.regexp = ctx->deploy.jfrog[i].upload_ctx.regexp;
+ result->deploy.jfrog[i].upload_ctx.retries = ctx->deploy.jfrog[i].upload_ctx.retries;
+ result->deploy.jfrog[i].upload_ctx.retry_wait_time = ctx->deploy.jfrog[i].upload_ctx.retry_wait_time;
+ result->deploy.jfrog[i].upload_ctx.spec = strdup_maybe(ctx->deploy.jfrog[i].upload_ctx.spec);
+ result->deploy.jfrog[i].upload_ctx.spec_vars = strdup_maybe(ctx->deploy.jfrog[i].upload_ctx.spec_vars);
+ result->deploy.jfrog[i].upload_ctx.symlinks = ctx->deploy.jfrog[i].upload_ctx.symlinks;
+ result->deploy.jfrog[i].upload_ctx.sync_deletes = ctx->deploy.jfrog[i].upload_ctx.sync_deletes;
+ result->deploy.jfrog[i].upload_ctx.target_props = strdup_maybe(ctx->deploy.jfrog[i].upload_ctx.target_props);
+ result->deploy.jfrog[i].upload_ctx.threads = ctx->deploy.jfrog[i].upload_ctx.threads;
+ result->deploy.jfrog[i].upload_ctx.workaround_parent_only = ctx->deploy.jfrog[i].upload_ctx.workaround_parent_only;
+ }
+
+ result->deploy.jfrog_auth.access_token = strdup_maybe(ctx->deploy.jfrog_auth.access_token);
+ result->deploy.jfrog_auth.client_cert_key_path = strdup_maybe(ctx->deploy.jfrog_auth.client_cert_key_path);
+ result->deploy.jfrog_auth.client_cert_path = strdup_maybe(ctx->deploy.jfrog_auth.client_cert_path);
+ result->deploy.jfrog_auth.insecure_tls = ctx->deploy.jfrog_auth.insecure_tls;
+ result->deploy.jfrog_auth.password = strdup_maybe(ctx->deploy.jfrog_auth.password);
+ result->deploy.jfrog_auth.server_id = strdup_maybe(ctx->deploy.jfrog_auth.server_id);
+ result->deploy.jfrog_auth.ssh_key_path = strdup_maybe(ctx->deploy.jfrog_auth.ssh_key_path);
+ result->deploy.jfrog_auth.ssh_passphrase = strdup_maybe(ctx->deploy.jfrog_auth.ssh_passphrase);
+ result->deploy.jfrog_auth.url = strdup_maybe(ctx->deploy.jfrog_auth.url);
+ result->deploy.jfrog_auth.user = strdup_maybe(ctx->deploy.jfrog_auth.user);
+
+ for (size_t i = 0; i < sizeof(result->tests) / sizeof(result->tests[0]); i++) {
+ result->tests[i].disable = ctx->tests[i].disable;
+ result->tests[i].parallel = ctx->tests[i].parallel;
+ result->tests[i].build_recipe = strdup_maybe(ctx->tests[i].build_recipe);
+ result->tests[i].name = strdup_maybe(ctx->tests[i].name);
+ result->tests[i].version = strdup_maybe(ctx->tests[i].version);
+ result->tests[i].repository = strdup_maybe(ctx->tests[i].repository);
+ result->tests[i].repository_info_ref = strdup_maybe(ctx->tests[i].repository_info_ref);
+ result->tests[i].repository_info_tag = strdup_maybe(ctx->tests[i].repository_info_tag);
+ result->tests[i].repository_remove_tags = strlist_copy(ctx->tests[i].repository_remove_tags);
+ if (ctx->tests[i].runtime.environ) {
+ result->tests[i].runtime.environ = runtime_copy(ctx->tests[i].runtime.environ->data);
+ }
+ result->tests[i].script = strdup_maybe(ctx->tests[i].script);
+ result->tests[i].script_setup = strdup_maybe(ctx->tests[i].script_setup);
+ }
+
+ return result;
+}
+
void delivery_free(struct Delivery *ctx) {
guard_free(ctx->system.arch);
guard_array_free(ctx->system.platform);
diff --git a/src/lib/delivery/include/delivery.h b/src/lib/delivery/include/delivery.h
index 69ec089..f8229ed 100644
--- a/src/lib/delivery/include/delivery.h
+++ b/src/lib/delivery/include/delivery.h
@@ -64,10 +64,8 @@ struct Delivery {
* \brief System information
*/
struct System {
- char *arch;
- ///< System CPU architecture ident
- char **platform;
- ///< System platform name
+ char *arch; ///< System CPU architecture ident
+ char **platform; ///< System platform name
} system;
/*! \struct Storage
* \brief Storage paths
@@ -483,4 +481,11 @@ void delivery_rewrite_stage1(struct Delivery *ctx, char *specfile);
*/
void delivery_rewrite_stage2(struct Delivery *ctx, char *specfile);
+/**
+ * Return a copy of a delivery context
+ * @param ctx Delivery context
+ * @return a copy
+ */
+struct Delivery *delivery_duplicate(const struct Delivery *ctx);
+
#endif //STASIS_DELIVERY_H