Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make make(1): prevent undefined behavior in loadfile...



details:   https://anonhg.NetBSD.org/src/rev/27b338aeee59
branches:  trunk
changeset: 948237:27b338aeee59
user:      rillig <rillig%NetBSD.org@localhost>
date:      Tue Dec 22 06:48:33 2020 +0000

description:
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:

 usr.bin/make/parse.c |  22 ++++++++++++++++++++--
 1 files changed, 20 insertions(+), 2 deletions(-)

diffs (54 lines):

diff -r b3ad103374f6 -r 27b338aeee59 usr.bin/make/parse.c
--- a/usr.bin/make/parse.c      Tue Dec 22 01:58:58 2020 +0000
+++ b/usr.bin/make/parse.c      Tue Dec 22 06:48:33 2020 +0000
@@ -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 @@
                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 @@
                }
 
                /* 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)



Home | Main Index | Thread Index | Old Index