diff options
| author | rillig <rillig@NetBSD.org> | 2020-12-22 06:48:33 +0000 |
|---|---|---|
| committer | rillig <rillig@NetBSD.org> | 2020-12-22 06:48:33 +0000 |
| commit | 86352c2ba89324f6648233acbfa33431c08d14fe (patch) | |
| tree | ebfd58a34475d30e5e9d454faa533e260a6a9e6b /usr.bin/make/parse.c | |
| parent | a91a9a69622144e87a6864c71971d874ed65d543 (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.c | 22 |
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) |
