Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libc/stdio Avoid undefined behavior in fread(3)
details: https://anonhg.NetBSD.org/src/rev/01764d8c0f68
branches: trunk
changeset: 1007562:01764d8c0f68
user: kamil <kamil%NetBSD.org@localhost>
date: Sat Feb 22 22:02:46 2020 +0000
description:
Avoid undefined behavior in fread(3)
On the first call to fread(3), just after fopen(3) the internal buffers
are empty. This means that _r and _p (among others) are zeroed.
Passing NULL to the 2nd argument of memcpy(3) for the zero length is
undefined. Calling _p += 0 triggers LLVM UBSan (NULL pointer arithmetic).
Calling _p += 0, p += 0 and resid -= 0 has no effect.
Replace the "fp->_r = 0;" logic with a short circuit jump to __srefill()
that sets _r internally and refills the FILE buffers.
No functional change from an end user point of view, except skipping a few
dummy operations on the first call, for a FILE pointer, to fread(3).
diffstat:
lib/libc/stdio/fread.c | 13 +++++++++----
1 files changed, 9 insertions(+), 4 deletions(-)
diffs (42 lines):
diff -r 756a6f103813 -r 01764d8c0f68 lib/libc/stdio/fread.c
--- a/lib/libc/stdio/fread.c Sat Feb 22 21:59:30 2020 +0000
+++ b/lib/libc/stdio/fread.c Sat Feb 22 22:02:46 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fread.c,v 1.22 2012/03/15 18:22:30 christos Exp $ */
+/* $NetBSD: fread.c,v 1.23 2020/02/22 22:02:46 kamil Exp $ */
/*-
* Copyright (c) 1990, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)fread.c 8.2 (Berkeley) 12/11/93";
#else
-__RCSID("$NetBSD: fread.c,v 1.22 2012/03/15 18:22:30 christos Exp $");
+__RCSID("$NetBSD: fread.c,v 1.23 2020/02/22 22:02:46 kamil Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -68,16 +68,21 @@
_DIAGASSERT(buf != NULL);
FLOCKFILE(fp);
- if (fp->_r < 0)
- fp->_r = 0;
total = resid;
p = buf;
+
+ if (fp->_r <= 0) {
+ /* Nothing to read on enter, refill the buffers. */
+ goto refill;
+ }
+
while (resid > (size_t)(r = fp->_r)) {
(void)memcpy(p, fp->_p, (size_t)r);
fp->_p += r;
/* fp->_r = 0 ... done in __srefill */
p += r;
resid -= r;
+refill:
if (__srefill(fp)) {
/* no more input: return partial result */
FUNLOCKFILE(fp);
Home |
Main Index |
Thread Index |
Old Index