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"