Module Name: src Committed By: rillig Date: Fri Feb 16 19:20:38 UTC 2024
Modified Files: src/common/lib/libutil: snprintb.c src/tests/lib/libutil: t_snprintb.c Log Message: snprintb: fix integer overflow when writing past a small buffer Previously, snprintb returned -1 in this case, assuming that the snprintf used in FMTSTR validates against an overly large buffer size. To generate a diff of this commit: cvs rdiff -u -r1.30 -r1.31 src/common/lib/libutil/snprintb.c cvs rdiff -u -r1.18 -r1.19 src/tests/lib/libutil/t_snprintb.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/common/lib/libutil/snprintb.c diff -u src/common/lib/libutil/snprintb.c:1.30 src/common/lib/libutil/snprintb.c:1.31 --- src/common/lib/libutil/snprintb.c:1.30 Fri Feb 16 18:17:10 2024 +++ src/common/lib/libutil/snprintb.c Fri Feb 16 19:20:38 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: snprintb.c,v 1.30 2024/02/16 18:17:10 rillig Exp $ */ +/* $NetBSD: snprintb.c,v 1.31 2024/02/16 19:20:38 rillig Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -41,7 +41,7 @@ # include <sys/cdefs.h> # if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: snprintb.c,v 1.30 2024/02/16 18:17:10 rillig Exp $"); +__RCSID("$NetBSD: snprintb.c,v 1.31 2024/02/16 19:20:38 rillig Exp $"); # endif # include <sys/types.h> @@ -51,7 +51,7 @@ __RCSID("$NetBSD: snprintb.c,v 1.30 2024 # include <errno.h> # else /* ! _KERNEL */ # include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: snprintb.c,v 1.30 2024/02/16 18:17:10 rillig Exp $"); +__KERNEL_RCSID(0, "$NetBSD: snprintb.c,v 1.31 2024/02/16 19:20:38 rillig Exp $"); # include <sys/param.h> # include <sys/inttypes.h> # include <sys/systm.h> @@ -171,8 +171,9 @@ snprintb_m(char *buf, size_t bufsize, co } while (0) #define FMTSTR(sb, f) do { \ - int fmt_len = snprintf(bp, bufsize - total_len, sb, \ - (uintmax_t)f); \ + size_t n = (size_t)total_len < bufsize \ + ? bufsize - total_len : 0; \ + int fmt_len = snprintf(bp, n, sb, (uintmax_t)f); \ if (fmt_len < 0) \ goto internal; \ total_len += fmt_len; \ Index: src/tests/lib/libutil/t_snprintb.c diff -u src/tests/lib/libutil/t_snprintb.c:1.18 src/tests/lib/libutil/t_snprintb.c:1.19 --- src/tests/lib/libutil/t_snprintb.c:1.18 Fri Feb 16 18:13:47 2024 +++ src/tests/lib/libutil/t_snprintb.c Fri Feb 16 19:20:38 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: t_snprintb.c,v 1.18 2024/02/16 18:13:47 rillig Exp $ */ +/* $NetBSD: t_snprintb.c,v 1.19 2024/02/16 19:20:38 rillig Exp $ */ /* * Copyright (c) 2002, 2004, 2008, 2010, 2024 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ #include <sys/cdefs.h> __COPYRIGHT("@(#) Copyright (c) 2008, 2010\ The NetBSD Foundation, inc. All rights reserved."); -__RCSID("$NetBSD: t_snprintb.c,v 1.18 2024/02/16 18:13:47 rillig Exp $"); +__RCSID("$NetBSD: t_snprintb.c,v 1.19 2024/02/16 19:20:38 rillig Exp $"); #include <stdio.h> #include <string.h> @@ -893,6 +893,32 @@ ATF_TC_BODY(snprintb_m, tc) "0xff<bits=0xf=fall\0" ); + // new-style format, buffer too small for numeric fallback + h_snprintb_m_len( + 20, + "\177\020" + "F\000\004\0" + "*fallback(%040jd)\0", + 0xff, + 64, + 57, + "0xff<fallback(0000\0" + ); + + // new-style format, buffer too small for numeric fallback past buffer + h_snprintb_m_len( + 15, + "\177\020" + "F\000\004\0" + "*fallback(%010jd)\0" + "F\004\004\0" + "*fallback(%010jd)\0", + 0xff, + 64, + 48, + "0xff<fallback\0" + ); + h_snprintb_m( "\177\020" "b\0LSB\0"