The branch main has been updated by fuz: URL: https://cgit.FreeBSD.org/src/commit/?id=3501eec9dd39b527a46e82de53480968d283b90e
commit 3501eec9dd39b527a46e82de53480968d283b90e Author: Faraz Vahedi <[email protected]> AuthorDate: 2026-05-28 13:50:45 +0000 Commit: Robert Clausecker <[email protected]> CommitDate: 2026-06-07 20:59:18 +0000 libc: Guard mergesort() allocation size arithmetic Signed-off-by: Faraz Vahedi <[email protected]> Pull Request: https://github.com/freebsd/freebsd-src/pull/2243 Reviewed by: fuz MFC after: 1 week --- lib/libc/stdlib/merge.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/libc/stdlib/merge.c b/lib/libc/stdlib/merge.c index e70938088589..e07a3947e741 100644 --- a/lib/libc/stdlib/merge.c +++ b/lib/libc/stdlib/merge.c @@ -49,6 +49,7 @@ #include <sys/param.h> #include <errno.h> +#include <stdckdint.h> #include <stdlib.h> #include <string.h> @@ -109,7 +110,7 @@ mergesort_b(void *base, size_t nmemb, size_t size, cmp_t cmp) mergesort(void *base, size_t nmemb, size_t size, cmp_t cmp) #endif { - size_t i; + size_t i, nbytes, asize; int sense; int big, iflag; u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2; @@ -123,16 +124,21 @@ mergesort(void *base, size_t nmemb, size_t size, cmp_t cmp) if (nmemb == 0) return (0); + if (ckd_mul(&nbytes, nmemb, size) || ckd_add(&asize, nbytes, PSIZE)) { + errno = EINVAL; + return (-1); + } + iflag = 0; if (__is_aligned(size, ISIZE) && __is_aligned(base, ISIZE)) iflag = 1; - if ((list2 = malloc(nmemb * size + PSIZE)) == NULL) + if ((list2 = malloc(asize)) == NULL) return (-1); list1 = base; setup(list1, list2, nmemb, size, cmp); - last = list2 + nmemb * size; + last = list2 + nbytes; i = big = 0; while (*EVAL(list2) != last) { l2 = list1; @@ -227,10 +233,10 @@ COPY: b = t; tp2 = list1; /* swap list1, list2 */ list1 = list2; list2 = tp2; - last = list2 + nmemb*size; + last = list2 + nbytes; } if (base == list2) { - memmove(list2, list1, nmemb*size); + memmove(list2, list1, nbytes); list2 = list1; } free(list2);
