From e4d6ffc40395b2e49b110aafd5c816a56bf277e5 Mon Sep 17 00:00:00 2001 From: GreekStapler Date: Tue, 31 Jan 2023 21:00:08 +0000 Subject: [PATCH] fix: Using snprintf while ignoring its return value could lead to valid inputs getting truncated. --- include/vieter_package.h | 10 ++----- src/package/vieter_package.c | 51 ++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/include/vieter_package.h b/include/vieter_package.h index 179ff57..32fb0eb 100644 --- a/include/vieter_package.h +++ b/include/vieter_package.h @@ -1,16 +1,10 @@ #ifndef VIETER_PACKAGE #define VIETER_PACKAGE -#include -#include -#include -#include - -#include -#include - typedef struct vieter_package vieter_package; + + /* * Parse package file into something usable by libvieter. * The pointer returned by this function will need to freed at a later point. diff --git a/src/package/vieter_package.c b/src/package/vieter_package.c index 3bb19ba..031fe15 100644 --- a/src/package/vieter_package.c +++ b/src/package/vieter_package.c @@ -1,30 +1,29 @@ +#include +#include +#include +#include + #include "vieter_package_internal.h" #include "sha256.h" -#define SMALL_BUFF_SIZE 128 - #define ADD_STRING(section, field) if (pkg_info->field != 0) { \ - snprintf(aux, SMALL_BUFF_SIZE, section, pkg_info->field); \ - if (buff_size < strlen(description) + SMALL_BUFF_SIZE + 1) { \ + size_to_be_written = snprintf(aux, small_buff_size, section, pkg_info->field); \ + if (size_to_be_written > small_buff_size) { \ + aux = realloc(aux, size_to_be_written + 1); \ + small_buff_size = size_to_be_written + 1; \ + snprintf(aux, small_buff_size, section, pkg_info->field); \ + } \ + if (buff_size < strlen(description) + small_buff_size + 1) { \ description = realloc(description, buff_size * 2); \ buff_size *= 2; \ } \ strcat(description, aux); \ } + #define ADD_ARRAY(section, field) i = 0; if (pkg_info->field != NULL) { \ - snprintf(aux, SMALL_BUFF_SIZE, section, pkg_info->field->array[i]); i++; \ - if (buff_size < strlen(description) + SMALL_BUFF_SIZE + 1) { \ - description = realloc(description, buff_size * 2); \ - buff_size *= 2; \ - } \ - strcat(description, aux); \ + ADD_STRING(section, field->array[i]); i++; \ while (pkg_info->field->array[i] != NULL) { \ - snprintf(aux, SMALL_BUFF_SIZE, "\n%s", pkg_info->field->array[i]); i++; \ - if (buff_size < strlen(description) + SMALL_BUFF_SIZE + 1) { \ - description = realloc(description, buff_size * 2); \ - buff_size *= 2; \ - } \ - strcat(description, aux); \ + ADD_STRING("\n%s", field->array[i]); i++; \ } \ } @@ -170,19 +169,32 @@ void vieter_package_sha256sum(vieter_package *pkg, char *res) { res[j] = '\0'; } + + char *vieter_package_to_description(vieter_package *pkg) { vieter_package_info *pkg_info = pkg->info; size_t buff_size = 1024; - char aux[SMALL_BUFF_SIZE]; + int small_buff_size = 128; + int size_to_be_written; + char *aux = malloc(sizeof(char) * small_buff_size); char *description = malloc(sizeof(char) * buff_size); // Helper variable for ADD_ARRAY macro int i; // special case for FILENAME // assuming .pkg.tar.zst; other formats are valid, this should account for that - snprintf(aux, SMALL_BUFF_SIZE, "%%FILENAME%%\n%s-%s-%s.pkg.tar.zst", pkg_info->name, + size_to_be_written = snprintf(aux, small_buff_size, "%%FILENAME%%\n%s-%s-%s.pkg.tar.zst", pkg_info->name, pkg_info->version, pkg_info->arch); + + // We neither want to let an arbritrarily long input to overflow the buffer + // nor to truncate perfectly valid inputs + if (size_to_be_written > small_buff_size) { + aux = realloc(aux, size_to_be_written + 1); + small_buff_size = size_to_be_written + 1; + snprintf(aux, small_buff_size, "%%FILENAME%%\n%s-%s-%s.pkg.tar.zst", pkg_info->name, + pkg_info->version, pkg_info->arch); + } strcpy(description, aux); ADD_STRING("\n\n%%NAME%%\n%s", name); @@ -216,8 +228,7 @@ char *vieter_package_to_description(vieter_package *pkg) { ADD_ARRAY("\n\n%%MAKEDEPENDS%%\n%s", makedepends); ADD_ARRAY("\n\n%%CHECKDEPENDS%%\n%s", checkdepends); - snprintf(aux, SMALL_BUFF_SIZE, "\n\n"); - strcat(description, aux); + strcat(description, "\n\n"); return description; }