about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2021-09-11 21:21:43 -0400
committerRich Felker <dalias@aerifal.cx>2021-09-11 21:21:43 -0400
commite3e7189c11d909199155327fd6a93dcc6b68c7b3 (patch)
treeb0a391e0975ca632b07c32bfea804fcaca27a515
parentb713b8b2e4b9595eec72ec3c4fe7714076d60478 (diff)
downloadmusl-e3e7189c11d909199155327fd6a93dcc6b68c7b3.tar.gz
musl-e3e7189c11d909199155327fd6a93dcc6b68c7b3.tar.xz
musl-e3e7189c11d909199155327fd6a93dcc6b68c7b3.zip
fix undefined behavior in getdelim via null pointer arithmetic and memcpy
both passing a null pointer to memcpy with length 0, and adding 0 to a
null pointer, are undefined. in some sense this is 'benign' UB, but
having it precludes use of tooling that strictly traps on UB. there
may be better ways to fix it, but conditioning the operations which
are intended to be no-ops in the k==0 case on k being nonzero is a
simple and safe solution.
-rw-r--r--src/stdio/getdelim.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/src/stdio/getdelim.c b/src/stdio/getdelim.c
index d2f5b15a..df114441 100644
--- a/src/stdio/getdelim.c
+++ b/src/stdio/getdelim.c
@@ -55,9 +55,11 @@ ssize_t getdelim(char **restrict s, size_t *restrict n, int delim, FILE *restric
 			*s = tmp;
 			*n = m;
 		}
-		memcpy(*s+i, f->rpos, k);
-		f->rpos += k;
-		i += k;
+		if (k) {
+			memcpy(*s+i, f->rpos, k);
+			f->rpos += k;
+			i += k;
+		}
 		if (z) break;
 		if ((c = getc_unlocked(f)) == EOF) {
 			if (!i || !feof(f)) {