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