richardphibel / rpms / rpm

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