From fde12434432f51ed773957824aa9460f5cc99e85 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Tue, 11 Jan 2022 18:55:41 +0100 Subject: Fix out of boundary writes in XUtils It is possible to exceed the unsigned int data type on 64 bit systems with enough available RAM. Use size_t in all places instead. Proof of Concept: Create a 4 GB line in .htoprc file and run htop $ dd if=/dev/zero bs=1024 count=4194304 | tr '\0' 'a' > ~/.htoprc $ htop Segmentation fault Also avoid overflow of stack based "match" array in String_getToken. --- XUtils.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/XUtils.c b/XUtils.c index b6999f92..96e93cbb 100644 --- a/XUtils.c +++ b/XUtils.c @@ -101,6 +101,7 @@ inline bool String_contains_i(const char* s1, const char* s2) { char* String_cat(const char* s1, const char* s2) { const size_t l1 = strlen(s1); const size_t l2 = strlen(s2); + assert(SIZE_MAX - l1 > l2); char* out = xMalloc(l1 + l2 + 1); memcpy(out, s1, l1); memcpy(out + l1, s2, l2); @@ -122,10 +123,10 @@ char* String_trim(const char* in) { } char** String_split(const char* s, char sep, size_t* n) { - const unsigned int rate = 10; + const size_t rate = 10; char** out = xCalloc(rate, sizeof(char*)); size_t ctr = 0; - unsigned int blocks = rate; + size_t blocks = rate; const char* where; while ((where = strchr(s, sep)) != NULL) { size_t size = (size_t)(where - s); @@ -177,6 +178,8 @@ char* String_getToken(const char* line, const unsigned short int numMatch) { if (inWord == 1) { if (count == numMatch && line[i] != ' ' && line[i] != '\0' && line[i] != '\n' && line[i] != (char)EOF) { + if (foundCount == sizeof(match) / sizeof(match[0]) - 1) + break; match[foundCount] = line[i]; foundCount++; } @@ -188,8 +191,8 @@ char* String_getToken(const char* line, const unsigned short int numMatch) { } char* String_readLine(FILE* fd) { - const unsigned int step = 1024; - unsigned int bufSize = step; + const size_t step = 1024; + size_t bufSize = step; char* buffer = xMalloc(step + 1); char* at = buffer; for (;;) { -- cgit v1.2.3