From 937f9bc67b905851c78719d8397926eaa97b174a Mon Sep 17 00:00:00 2001 From: Richard Phibel Date: Mon, 22 May 2023 05:16:51 +0200 Subject: [PATCH] Fix stack overflow Creation of array struct digestoffset offsets[rpmfiFC(fi)] caused a stack overflow because the total size is greater than 8M which is the stack size limit on Linux. To fix the issue, the array is allocated on the heap. I used AddressSanitizer to find the root cause of the issue. It found a number of memory leaks so I fixed them as well. --- rpm2extents.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/rpm2extents.c b/rpm2extents.c index c2a373914..0ee8666fa 100644 --- a/rpm2extents.c +++ b/rpm2extents.c @@ -226,6 +226,7 @@ exit: if(msg) { free(msg); } + rpmtsFree(ts); return rc; } @@ -243,6 +244,7 @@ static void sanitizeSignatureHeader(Header * sigh) *sigh = headerLink(nh); headerFree(nh); } + rpmtdFreeData(&td); } static rpmRC process_package(FD_t fdi, FD_t digestori, FD_t validationi) @@ -281,6 +283,8 @@ static rpmRC process_package(FD_t fdi, FD_t digestori, FD_t validationi) rpmfiles files = NULL; rpmfi fi = NULL; char *msg = NULL; + struct digestoffset *offsets = NULL; + digestSet ds = NULL; fdo = fdDup(STDOUT_FILENO); @@ -357,10 +361,8 @@ static rpmRC process_package(FD_t fdi, FD_t digestori, FD_t validationi) * now?) */ diglen = (uint32_t) rpmDigestLength(rpmfiDigestAlgo(fi)); - digestSet ds = - digestSetCreate(rpmfiFC(fi), digestSetHash, digestSetCmp, - NULL); - struct digestoffset offsets[rpmfiFC(fi)]; + ds = digestSetCreate(rpmfiFC(fi), digestSetHash, digestSetCmp, NULL); + offsets = xcalloc(rpmfiFC(fi), sizeof(*offsets)); pos = RPMLEAD_SIZE + headerSizeof(sigh, HEADER_MAGIC_YES); /* main headers are aligned to 8 byte boundry */ @@ -494,6 +496,10 @@ static rpmRC process_package(FD_t fdi, FD_t digestori, FD_t validationi) rpmfilesFree(files); rpmfiFree(fi); headerFree(h); + headerFree(sigh); + free(offsets); + Fclose(fdo); + digestSetFree(ds); return rc; } @@ -693,6 +699,7 @@ int main(int argc, char *argv[]) { FD_t fdi = fdDup(STDIN_FILENO); rc = teeRpm(fdi, algos, nb_algos); + Fclose(fdi); if (rc != RPMRC_OK) { /* translate rpmRC into generic failure return code. */ return EXIT_FAILURE; -- 2.40.1