summaryrefslogtreecommitdiff
path: root/usr.bin/make/parse.c
diff options
context:
space:
mode:
authorrillig <rillig@NetBSD.org>2020-12-22 06:48:33 +0000
committerrillig <rillig@NetBSD.org>2020-12-22 06:48:33 +0000
commit86352c2ba89324f6648233acbfa33431c08d14fe (patch)
treeebfd58a34475d30e5e9d454faa533e260a6a9e6b /usr.bin/make/parse.c
parenta91a9a69622144e87a6864c71971d874ed65d543 (diff)
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.
Diffstat (limited to 'usr.bin/make/parse.c')
-rw-r--r--usr.bin/make/parse.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/usr.bin/make/parse.c b/usr.bin/make/parse.c
index f6dbb511323..db6fca0f002 100644
--- a/usr.bin/make/parse.c
+++ b/usr.bin/make/parse.c
@@ -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_line, char **out_line_end,
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)