Module Name: src
Committed By: rillig
Date: Tue Dec 22 06:48:33 UTC 2020
Modified Files:
src/usr.bin/make: parse.c
Log Message:
make(1): prevent undefined behavior in loadfile_mmap
Reading a file without a trailing newline had resulted in an
out-of-bounds write, in the common case where the file is loaded via
mmap.
To generate a diff of this commit:
cvs rdiff -u -r1.509 -r1.510 src/usr.bin/make/parse.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/make/parse.c
diff -u src/usr.bin/make/parse.c:1.509 src/usr.bin/make/parse.c:1.510
--- src/usr.bin/make/parse.c:1.509 Mon Dec 21 02:09:34 2020
+++ src/usr.bin/make/parse.c Tue Dec 22 06:48:33 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.509 2020/12/21 02:09:34 rillig Exp $ */
+/* $NetBSD: parse.c,v 1.510 2020/12/22 06:48:33 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -117,7 +117,7 @@
#include "pathnames.h"
/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: parse.c,v 1.509 2020/12/21 02:09:34 rillig Exp $");
+MAKE_RCSID("$NetBSD: parse.c,v 1.510 2020/12/22 06:48:33 rillig Exp $");
/* types and constants */
@@ -2687,10 +2687,22 @@ ParseRawLine(IFile *curFile, char **out_
if (ch == '\\') {
if (firstBackslash == NULL)
firstBackslash = p;
+ /*
+ * FIXME: In opt-file.mk, this command succeeds:
+ * printf '%s' 'V=v\' | make -r -f -
+ * Using an intermediate file fails though:
+ * printf '%s' 'V=v\' > backslash
+ * make -r -f backslash
+ *
+ * In loadedfile_mmap, the trailing newline is not
+ * added in every case, only if the file ends at a
+ * page boundary.
+ */
if (p[1] == '\n')
curFile->lineno++;
p += 2;
line_end = p;
+ assert(p <= curFile->buf_end);
continue;
}
@@ -2831,6 +2843,12 @@ ParseGetLine(GetLineMode mode)
}
/* We now have a line of data */
+ /*
+ * FIXME: undefined behavior since line_end points right
+ * after the allocated buffer. This becomes apparent when
+ * using a strict malloc implementation that adds canaries
+ * before and after the allocated space.
+ */
*line_end = '\0';
if (mode == GLM_FOR_BODY)