From c061da4fd42eb98ec3ac4e80a75e63924e21b437 Mon Sep 17 00:00:00 2001
From: Zoltan Fridrich <zfridric@redhat.com>
Date: Wed, 18 May 2022 11:43:26 +0200
Subject: [PATCH] Fix out-of-bounds memcpy in gnutls_realloc_zero()

Co-authored-by: Tobias Heider <tobias.heider@canonical.com>
Co-authored-by: Daiki Ueno <ueno@gnu.org>
Signed-off-by: Zoltan Fridrich <zfridric@redhat.com>
---
 lib/nettle/init.c | 46 ++++++++++++++++++----------------------------
 1 file changed, 18 insertions(+), 28 deletions(-)

diff --git a/lib/nettle/init.c b/lib/nettle/init.c
index ddbc3ab624..d06faf941e 100644
--- a/lib/nettle/init.c
+++ b/lib/nettle/init.c
@@ -94,42 +94,32 @@ static void gnutls_free_zero(void *data, size_t size)
  -*/
 static void *gnutls_realloc_zero(void *data, size_t old_size, size_t new_size)
 {
-	void *newptr = NULL;
+	void *p;
 
-	/* mini-gmp always passes old_size of 0 */
-	if (old_size == 0) {
-		newptr = realloc(data, new_size);
-		if (newptr == NULL)
+	if (data == NULL || old_size == 0) {
+		p = realloc(data, new_size);
+		if (p == NULL)
 			abort();
-		return newptr;
+		return p;
 	}
 
-	if (data == NULL) {
-		newptr = malloc(new_size);
-		if (newptr == NULL)
-			abort();
-		return newptr;
+	if (new_size == 0) {
+		explicit_bzero(data, old_size);
+		free(data);
+		return NULL;
 	}
 
-	if (new_size == 0)
-		goto done;
-
-	if (new_size <= old_size) {
-		size_t d = old_size - new_size;
-		/* Don't bother reallocating */
-		if (d < old_size / 2) {
-			explicit_bzero((char *)data + new_size, d);
-			return data;
-		}
-	}
+	if (old_size == new_size)
+		return data;
 
-	newptr = malloc(new_size);
-	if (newptr == NULL)
+	p = malloc(new_size);
+	if (p == NULL) {
+		explicit_bzero(data, old_size);
 		abort();
-
-	memcpy(newptr, data, old_size);
- done:
+	}
+	memcpy(p, data, MIN(old_size, new_size));
 	explicit_bzero(data, old_size);
 	free(data);
-	return newptr;
+
+	return p;
 }
-- 
GitLab

