Module Name:    src
Committed By:   shm
Date:           Fri Sep  8 14:34:02 UTC 2023

Modified Files:
        src/usr.bin/mail: format.c

Log Message:
Fix check_bufsize() incorrect behaviour

The function ensures that that buffer is large enough to store the data (if
not, it reallocates it). It doubled the buffer every time the buffer was too
small, but in some cases it wasn't enough, which might lead to heap overflows.
Rewrite of this function handles int overflow scenarios as well as ensures the
buffer is big enough to handle the data.

Thanks riastradh@ for the review and comments


To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.18 src/usr.bin/mail/format.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/mail/format.c
diff -u src/usr.bin/mail/format.c:1.17 src/usr.bin/mail/format.c:1.18
--- src/usr.bin/mail/format.c:1.17	Sun Aug  7 10:12:19 2022
+++ src/usr.bin/mail/format.c	Fri Sep  8 14:34:02 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: format.c,v 1.17 2022/08/07 10:12:19 andvar Exp $	*/
+/*	$NetBSD: format.c,v 1.18 2023/09/08 14:34:02 shm Exp $	*/
 
 /*-
  * Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #ifndef __lint__
-__RCSID("$NetBSD: format.c,v 1.17 2022/08/07 10:12:19 andvar Exp $");
+__RCSID("$NetBSD: format.c,v 1.18 2023/09/08 14:34:02 shm Exp $");
 #endif /* not __lint__ */
 
 #include <time.h>
@@ -54,13 +54,21 @@ __RCSID("$NetBSD: format.c,v 1.17 2022/0
 static void
 check_bufsize(char **buf, size_t *bufsize, char **p, size_t cnt)
 {
-	char *q;
-	if (*p + cnt < *buf + *bufsize)
+	size_t offset = (size_t)(*p - *buf);
+
+	/* enough buffer allocated already */
+	if (cnt < *bufsize - offset)
 		return;
-	*bufsize *= 2;
-	q = erealloc(*buf, *bufsize);
-	*p = q + (*p - *buf);
-	*buf = q;
+
+	/* expand buffer till it's sufficient to handle the data */
+	while (cnt >= *bufsize - offset) {
+		if (*bufsize > SIZE_MAX/2)
+			errx(1, "out of memory");
+		*bufsize *= 2;
+	}
+
+	*buf = erealloc(*buf, *bufsize);
+	*p = *buf + offset;
 }
 
 static const char *

Reply via email to