From 9ac3db8e63a59bdd6e4055f2f0498760985b5f42 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 18 May 2026 14:19:35 +0200 Subject: [PATCH] swid-gen: Use process_t to avoid potential command injection In a targeted request, the software ID is provided by the IMV. If no database is used (which is not the recommended setup), the ID is not validated and could potentially contain special characters. With the previous command string construction and use of popen(), which runs a shell, that could potentially allow running arbitrary commands. --- src/libimcv/swid_gen/swid_gen.c | 52 +++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/src/libimcv/swid_gen/swid_gen.c b/src/libimcv/swid_gen/swid_gen.c index 36679a260..309d82d78 100644 --- a/src/libimcv/swid_gen/swid_gen.c +++ b/src/libimcv/swid_gen/swid_gen.c @@ -16,10 +16,12 @@ #define _GNU_SOURCE #include +#include #include "swid_gen.h" #include +#include #define SWID_GENERATOR "/usr/local/bin/swid_generator" @@ -57,31 +59,50 @@ METHOD(swid_gen_t, generate_tag, char*, private_swid_gen_t *this, char *sw_id, char *package, char *version, bool full, bool pretty) { + process_t *process; char *tag = NULL; size_t tag_buf_len = 8192; - char tag_buf[tag_buf_len], command[BUF_LEN]; + char tag_buf[tag_buf_len], *argv[12] = {}; bio_writer_t *writer; chunk_t swid_tag; FILE *file; + int i = 0, out; + + argv[i++] = this->generator; + argv[i++] = "swid"; + argv[i++] = "--entity-name"; + argv[i++] = this->entity; + argv[i++] = "--regid"; + argv[i++] = this->regid; - /* Compose the SWID generator command */ if (full || !package || !version) { - snprintf(command, BUF_LEN, "%s swid --entity-name \"%s\" " - "--regid %s --software-id %s%s%s", - this->generator, this->entity, this->regid, sw_id, - full ? " --full" : "", pretty ? " --pretty" : ""); + argv[i++] = "--software-id"; + argv[i++] = sw_id; + if (full) + { + argv[i++] = "--full"; + } } else { - snprintf(command, BUF_LEN, "%s swid --entity-name \"%s\" " - "--regid %s --name %s --version-string %s%s", - this->generator, this->entity, this->regid, package, - version, pretty ? " --pretty" : ""); + argv[i++] = "--name"; + argv[i++] = package; + argv[i++] = "--version-string"; + argv[i++] = version; + } + if (pretty) + { + argv[i++] = "--pretty"; } - /* Open a pipe stream for reading the SWID generator output */ - file = popen(command, "r"); + process = process_start(argv, NULL, NULL, &out, NULL, TRUE); + if (!process) + { + DBG1(DBG_IMC, "failed to run swid_generator command"); + return NULL; + } + file = fdopen(out, "r"); if (file) { writer = bio_writer_create(tag_buf_len); @@ -93,7 +114,8 @@ METHOD(swid_gen_t, generate_tag, char*, } writer->write_data(writer, chunk_create(tag_buf, strlen(tag_buf))); } - pclose(file); + fclose(file); + swid_tag = writer->extract_buf(writer); writer->destroy(writer); @@ -109,9 +131,9 @@ METHOD(swid_gen_t, generate_tag, char*, } else { - DBG1(DBG_IMC, "failed to run swid_generator command"); + close(out); } - + process->wait(process, NULL); return tag; }