Blame SOURCES/CVE-2022-39377-arithmetic-overflow-in-allocate-structures-on-32-bit-systems.patch

84e34f
From 9c4eaf150662ad40607923389d4519bc83b93540 Mon Sep 17 00:00:00 2001
84e34f
From: Sebastien <seb@fedora-2.home>
84e34f
Date: Sat, 15 Oct 2022 14:24:22 +0200
84e34f
Subject: [PATCH] Fix size_t overflow in sa_common.c (GHSL-2022-074)
84e34f
84e34f
allocate_structures function located in sa_common.c insufficiently
84e34f
checks bounds before arithmetic multiplication allowing for an
84e34f
overflow in the size allocated for the buffer representing system
84e34f
activities.
84e34f
84e34f
This patch checks that the post-multiplied value is not greater than
84e34f
UINT_MAX.
84e34f
84e34f
Signed-off-by: Sebastien <seb@fedora-2.home>
84e34f
---
84e34f
 common.c    | 25 +++++++++++++++++++++++++
84e34f
 common.h    |  2 ++
84e34f
 sa_common.c |  6 ++++++
84e34f
 3 files changed, 33 insertions(+)
84e34f
84e34f
diff --git a/common.c b/common.c
84e34f
index 81c77624..1a84b052 100644
84e34f
--- a/common.c
84e34f
+++ b/common.c
84e34f
@@ -1655,4 +1655,29 @@ int parse_values(char *strargv, unsigned char bitmap[], int max_val, const char
84e34f
 
84e34f
 	return 0;
84e34f
 }
84e34f
+
84e34f
+/*
84e34f
+ ***************************************************************************
84e34f
+ * Check if the multiplication of the 3 values may be greater than UINT_MAX.
84e34f
+ *
84e34f
+ * IN:
84e34f
+ * @val1	First value.
84e34f
+ * @val2	Second value.
84e34f
+ * @val3	Third value.
84e34f
+ ***************************************************************************
84e34f
+ */
84e34f
+void check_overflow(size_t val1, size_t val2, size_t val3)
84e34f
+{
84e34f
+	if ((unsigned long long) val1 *
84e34f
+	    (unsigned long long) val2 *
84e34f
+	    (unsigned long long) val3 > UINT_MAX) {
84e34f
+#ifdef DEBUG
84e34f
+		fprintf(stderr, "%s: Overflow detected (%llu). Aborting...\n",
84e34f
+			__FUNCTION__,
84e34f
+			(unsigned long long) val1 * (unsigned long long) val2 *	(unsigned long long) val3);
84e34f
+#endif
84e34f
+	exit(4);
84e34f
+	}
84e34f
+}
84e34f
+
84e34f
 #endif /* SOURCE_SADC undefined */
84e34f
diff --git a/common.h b/common.h
84e34f
index 55b6657d..e8ab98ab 100644
84e34f
--- a/common.h
84e34f
+++ b/common.h
84e34f
@@ -260,6 +260,8 @@ int check_dir
84e34f
 	(const char *, int);
84e34f
 
84e34f
 #ifndef SOURCE_SADC
84e34f
+void check_overflow
84e34f
+	(size_t, size_t, size_t);
84e34f
 int count_bits
84e34f
 	(void *, int);
84e34f
 int count_csvalues
84e34f
diff --git a/sa_common.c b/sa_common.c
84e34f
index 3699a840..b2cec4ad 100644
84e34f
--- a/sa_common.c
84e34f
+++ b/sa_common.c
84e34f
@@ -459,7 +459,13 @@ void allocate_structures(struct activity *act[])
84e34f
 	int i, j;
84e34f
 
84e34f
 	for (i = 0; i < NR_ACT; i++) {
84e34f
+
84e34f
 		if (act[i]->nr_ini > 0) {
84e34f
+
84e34f
+			/* Look for a possible overflow */
84e34f
+			check_overflow((size_t) act[i]->msize, (size_t) act[i]->nr_ini,
84e34f
+				       (size_t) act[i]->nr2);
84e34f
+
84e34f
 			for (j = 0; j < 3; j++) {
84e34f
 				SREALLOC(act[i]->buf[j], void,
84e34f
 						(size_t) act[i]->msize * (size_t) act[i]->nr_ini * (size_t) act[i]->nr2);