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 *