From e7749f1658cd4589e4d2f2deb604e780f818fdbc Mon Sep 17 00:00:00 2001 From: Rishi Jat Date: Sun, 26 Apr 2026 12:00:32 +0530 Subject: [PATCH 1/3] validate env limits in qfile-dom0-unpacker Signed-off-by: Rishi Jat --- dom0-updates/qfile-dom0-unpacker.c | 32 ++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/dom0-updates/qfile-dom0-unpacker.c b/dom0-updates/qfile-dom0-unpacker.c index 5b5dc07f..12e4061e 100644 --- a/dom0-updates/qfile-dom0-unpacker.c +++ b/dom0-updates/qfile-dom0-unpacker.c @@ -19,6 +19,32 @@ #define min(a,b) ((a) < (b) ? (a) : (b)) #define max(a,b) ((a) > (b) ? (a) : (b)) +static long long parse_limit_env(const char *name, long long fallback) +{ + const char *value = getenv(name); + if (!value) + return fallback; + + if (*value < '0' || *value > '9') { + fprintf(stderr, "Invalid value for %s: %s\n", name, value); + exit(1); + } + + errno = 0; + char *end = NULL; + long long limit = strtoll(value, &end, 10); + if (errno == ERANGE || *end != '\0' || limit < 0) { + fprintf(stderr, "Invalid value for %s: %s\n", name, value); + exit(1); + } + if (limit == 0 && strcmp(value, "0") != 0) { + fprintf(stderr, "Invalid value for %s: %s\n", name, value); + exit(1); + } + + return limit; +} + int prepare_creds_return_uid(const char *username) { struct passwd *pwd; @@ -88,10 +114,8 @@ int main(int argc, char ** argv) perror("Failed to check free space"); } - if ((var=getenv("UPDATES_MAX_BYTES"))) - bytes_limit = atoll(var); - if ((var=getenv("UPDATES_MAX_FILES"))) - files_limit = atoll(var); + bytes_limit = parse_limit_env("UPDATES_MAX_BYTES", bytes_limit); + files_limit = parse_limit_env("UPDATES_MAX_FILES", files_limit); set_size_limit(bytes_limit, files_limit); From 3cc072c405d0d159ae4bb1e6ae6d53fe53ce9e9e Mon Sep 17 00:00:00 2001 From: Rishi Jat Date: Sun, 14 Jun 2026 22:19:32 +0530 Subject: [PATCH 2/3] improve validation error messages - remove unreachable negative value check (never reached after initial digit check) - addresses reviewer note that some error paths seemed unreachable --- dom0-updates/qfile-dom0-unpacker.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dom0-updates/qfile-dom0-unpacker.c b/dom0-updates/qfile-dom0-unpacker.c index 12e4061e..a64d045b 100644 --- a/dom0-updates/qfile-dom0-unpacker.c +++ b/dom0-updates/qfile-dom0-unpacker.c @@ -26,19 +26,23 @@ static long long parse_limit_env(const char *name, long long fallback) return fallback; if (*value < '0' || *value > '9') { - fprintf(stderr, "Invalid value for %s: %s\n", name, value); + fprintf(stderr, "Invalid value for %s: %s: not a non-negative integer\n", name, value); exit(1); } errno = 0; char *end = NULL; long long limit = strtoll(value, &end, 10); - if (errno == ERANGE || *end != '\0' || limit < 0) { - fprintf(stderr, "Invalid value for %s: %s\n", name, value); + if (errno == ERANGE) { + fprintf(stderr, "Invalid value for %s: %s: out of range\n", name, value); + exit(1); + } + if (*end != '\0') { + fprintf(stderr, "Invalid value for %s: %s: trailing non-numeric characters\n", name, value); exit(1); } if (limit == 0 && strcmp(value, "0") != 0) { - fprintf(stderr, "Invalid value for %s: %s\n", name, value); + fprintf(stderr, "Invalid value for %s: %s: invalid zero representation\n", name, value); exit(1); } From f553089a9f10d6162d92aaac9d03821f646da30b Mon Sep 17 00:00:00 2001 From: Rishi Jat Date: Wed, 17 Jun 2026 05:30:08 +0530 Subject: [PATCH 3/3] qfile-dom0-unpacker: use shared integer parsing helper Signed-off-by: Rishi Jat --- dom0-updates/Makefile | 2 +- dom0-updates/qfile-dom0-unpacker.c | 21 ++++++--------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/dom0-updates/Makefile b/dom0-updates/Makefile index d1001d10..c3352013 100644 --- a/dom0-updates/Makefile +++ b/dom0-updates/Makefile @@ -1,4 +1,4 @@ CC=gcc CFLAGS=-g -I. -Wall -Wextra -Werror -fPIC -pie qfile-dom0-unpacker: qfile-dom0-unpacker.o - $(CC) -pie -g -o $@ $^ -lqubes-rpc-filecopy + $(CC) -pie -g -o $@ $^ -lqubes-rpc-filecopy -lqubes-pure diff --git a/dom0-updates/qfile-dom0-unpacker.c b/dom0-updates/qfile-dom0-unpacker.c index a64d045b..21d74d4f 100644 --- a/dom0-updates/qfile-dom0-unpacker.c +++ b/dom0-updates/qfile-dom0-unpacker.c @@ -12,6 +12,7 @@ #include #include #include +#include #define DEFAULT_MAX_UPDATES_BYTES (4LL<<30) #define DEFAULT_MAX_UPDATES_FILES 4096 @@ -25,24 +26,14 @@ static long long parse_limit_env(const char *name, long long fallback) if (!value) return fallback; - if (*value < '0' || *value > '9') { - fprintf(stderr, "Invalid value for %s: %s: not a non-negative integer\n", name, value); - exit(1); - } - - errno = 0; - char *end = NULL; - long long limit = strtoll(value, &end, 10); - if (errno == ERANGE) { + long long limit; + int rc = qubes_pure_parse_nonneg_ll(value, &limit); + if (rc == -ERANGE) { fprintf(stderr, "Invalid value for %s: %s: out of range\n", name, value); exit(1); } - if (*end != '\0') { - fprintf(stderr, "Invalid value for %s: %s: trailing non-numeric characters\n", name, value); - exit(1); - } - if (limit == 0 && strcmp(value, "0") != 0) { - fprintf(stderr, "Invalid value for %s: %s: invalid zero representation\n", name, value); + if (rc != 0) { + fprintf(stderr, "Invalid value for %s: %s: not a valid non-negative integer\n", name, value); exit(1); }