Source-Changes-HG archive

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

[src/trunk]: src/usr.bin/make/unit-tests make: fix use-after-free in modifier...



details:   https://anonhg.NetBSD.org/src/rev/9d15d187744c
branches:  trunk
changeset: 1026752:9d15d187744c
user:      rillig <rillig%NetBSD.org@localhost>
date:      Sun Dec 05 15:20:13 2021 +0000

description:
make: fix use-after-free in modifier ':@'

Without memory allocator debugging, the newly added test doesn't show
any obvious failure.

With memory allocator debugging enabled, all make versions since
2016.02.27.16.20.06 crash with a segmentation fault.

diffstat:

 distrib/sets/lists/tests/mi                    |   4 ++-
 usr.bin/make/unit-tests/Makefile               |   3 +-
 usr.bin/make/unit-tests/varmod-loop-delete.exp |   4 +++
 usr.bin/make/unit-tests/varmod-loop-delete.mk  |  33 ++++++++++++++++++++++++++
 usr.bin/make/unit-tests/varmod-loop.exp        |   1 -
 usr.bin/make/unit-tests/varmod-loop.mk         |  30 +----------------------
 usr.bin/make/var.c                             |  10 ++++++-
 7 files changed, 51 insertions(+), 34 deletions(-)

diffs (162 lines):

diff -r 3ec41249a9b2 -r 9d15d187744c distrib/sets/lists/tests/mi
--- a/distrib/sets/lists/tests/mi       Sun Dec 05 15:01:04 2021 +0000
+++ b/distrib/sets/lists/tests/mi       Sun Dec 05 15:20:13 2021 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1173 2021/11/28 16:20:13 rillig Exp $
+# $NetBSD: mi,v 1.1174 2021/12/05 15:20:13 rillig Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -5985,6 +5985,8 @@
 ./usr/tests/usr.bin/make/unit-tests/varmod-l-name-to-value.mk                  tests-usr.bin-tests     compattestfile,atf
 ./usr/tests/usr.bin/make/unit-tests/varmod-localtime.exp                       tests-usr.bin-tests     compattestfile,atf
 ./usr/tests/usr.bin/make/unit-tests/varmod-localtime.mk                                tests-usr.bin-tests     compattestfile,atf
+./usr/tests/usr.bin/make/unit-tests/varmod-loop-delete.exp                     tests-usr.bin-tests     compattestfile,atf
+./usr/tests/usr.bin/make/unit-tests/varmod-loop-delete.mk                      tests-usr.bin-tests     compattestfile,atf
 ./usr/tests/usr.bin/make/unit-tests/varmod-loop-varname.exp                    tests-usr.bin-tests     compattestfile,atf
 ./usr/tests/usr.bin/make/unit-tests/varmod-loop-varname.mk                     tests-usr.bin-tests     compattestfile,atf
 ./usr/tests/usr.bin/make/unit-tests/varmod-loop.exp                            tests-usr.bin-tests     compattestfile,atf
diff -r 3ec41249a9b2 -r 9d15d187744c usr.bin/make/unit-tests/Makefile
--- a/usr.bin/make/unit-tests/Makefile  Sun Dec 05 15:01:04 2021 +0000
+++ b/usr.bin/make/unit-tests/Makefile  Sun Dec 05 15:20:13 2021 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.285 2021/12/05 14:57:36 rillig Exp $
+# $NetBSD: Makefile,v 1.286 2021/12/05 15:20:13 rillig Exp $
 #
 # Unit tests for make(1)
 #
@@ -351,6 +351,7 @@
 TESTS+=                varmod-l-name-to-value
 TESTS+=                varmod-localtime
 TESTS+=                varmod-loop
+TESTS+=                varmod-loop-delete
 TESTS+=                varmod-loop-varname
 TESTS+=                varmod-match
 TESTS+=                varmod-match-escape
diff -r 3ec41249a9b2 -r 9d15d187744c usr.bin/make/unit-tests/varmod-loop-delete.exp
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/unit-tests/varmod-loop-delete.exp    Sun Dec 05 15:20:13 2021 +0000
@@ -0,0 +1,4 @@
+make: "varmod-loop-delete.mk" line 19: Cannot delete variable "VAR" while it is used.
+make: Fatal errors encountered -- cannot continue
+make: stopped in unit-tests
+exit status 1
diff -r 3ec41249a9b2 -r 9d15d187744c usr.bin/make/unit-tests/varmod-loop-delete.mk
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/unit-tests/varmod-loop-delete.mk     Sun Dec 05 15:20:13 2021 +0000
@@ -0,0 +1,33 @@
+# $NetBSD: varmod-loop-delete.mk,v 1.1 2021/12/05 15:20:13 rillig Exp $
+#
+# Tests for the variable modifier ':@', which as a side effect allows to
+# delete an arbitrary variable.
+
+# A side effect of the modifier ':@' is that the loop variable is created as
+# an actual variable in the current evaluation scope (Command/Global/target),
+# and at the end of the loop, this variable is deleted.  Before var.c 1.963
+# from 2021-12-05, a variable could be deleted while it was in use, leading to
+# a use-after-free bug.
+#
+# See Var_Parse, comment 'the value of the variable must not change'.
+
+# Set up the variable that deletes itself when it is evaluated.
+VAR=   ${:U:@VAR@@} rest of the value
+
+# In an assignment, the scope is 'Global'.  Since the variable 'VAR' is
+# defined in the global scope, it deletes itself.
+EVAL:= ${VAR}
+.if ${EVAL} != " rest of the value"
+.  error
+.endif
+
+VAR=   ${:U:@VAR@@} rest of the value
+all: .PHONY
+       # In the command that is associated with a target, the scope is the
+       # one from the target.  That scope only contains a few variables like
+       # '.TARGET', '.ALLSRC', '.IMPSRC'.  Make does not expect that these
+       # variables get modified from the outside.
+       #
+       # There is no variable named 'VAR' in the local scope, so nothing
+       # happens.
+       : $@: '${VAR}'
diff -r 3ec41249a9b2 -r 9d15d187744c usr.bin/make/unit-tests/varmod-loop.exp
--- a/usr.bin/make/unit-tests/varmod-loop.exp   Sun Dec 05 15:01:04 2021 +0000
+++ b/usr.bin/make/unit-tests/varmod-loop.exp   Sun Dec 05 15:20:13 2021 +0000
@@ -13,5 +13,4 @@
 mod-loop-dollar:$${word}$$:
 mod-loop-dollar:$$5$$:
 mod-loop-dollar:$$${word}$$$:
-: all: ' rest of the value'
 exit status 0
diff -r 3ec41249a9b2 -r 9d15d187744c usr.bin/make/unit-tests/varmod-loop.mk
--- a/usr.bin/make/unit-tests/varmod-loop.mk    Sun Dec 05 15:01:04 2021 +0000
+++ b/usr.bin/make/unit-tests/varmod-loop.mk    Sun Dec 05 15:20:13 2021 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-loop.mk,v 1.17 2021/12/05 15:01:04 rillig Exp $
+# $NetBSD: varmod-loop.mk,v 1.18 2021/12/05 15:20:13 rillig Exp $
 #
 # Tests for the :@var@...${var}...@ variable modifier.
 
@@ -186,32 +186,4 @@
 .  error                       # 'CMDLINE' is gone now from all scopes
 .endif
 
-
-# A side effect of the modifier ':@' is that the loop variable is created as
-# an actual variable in the current evaluation scope (Command/Global/target),
-# and at the end of the loop, this variable is deleted.  Before var.c 1.TODO
-# from 2021-12-05, a variable could be deleted while it was in use, leading to
-# a use-after-free bug.
-#
-# See Var_Parse, comment 'the value of the variable must not change'.
-
-# Set up the variable that deletes itself when it is evaluated.
-VAR=   ${:U:@VAR@@} rest of the value
-
-# In an assignment, the scope is 'Global'.  Since the variable 'VAR' is
-# defined in the global scope, it deletes itself.
-EVAL:= ${:U rest of the value} #${VAR} # FIXME: use-after-free
-.if ${EVAL} != " rest of the value"
-.  error
-.endif
-
-VAR=   ${:U:@VAR@@} rest of the value
 all: .PHONY
-       # In the command that is associated with a target, the scope is the
-       # one from the target.  That scope only contains a few variables like
-       # '.TARGET', '.ALLSRC', '.IMPSRC'.  Make does not expect that these
-       # variables get modified from the outside.
-       #
-       # There is no variable named 'VAR' in the local scope, so nothing
-       # happens.
-       : $@: '${VAR}'
diff -r 3ec41249a9b2 -r 9d15d187744c usr.bin/make/var.c
--- a/usr.bin/make/var.c        Sun Dec 05 15:01:04 2021 +0000
+++ b/usr.bin/make/var.c        Sun Dec 05 15:20:13 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: var.c,v 1.962 2021/12/05 12:17:49 rillig Exp $ */
+/*     $NetBSD: var.c,v 1.963 2021/12/05 15:20:13 rillig Exp $ */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -140,7 +140,7 @@
 #include "metachar.h"
 
 /*     "@(#)var.c      8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.962 2021/12/05 12:17:49 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.963 2021/12/05 15:20:13 rillig Exp $");
 
 /*
  * Variables are defined using one of the VAR=value assignments.  Their
@@ -496,6 +496,12 @@
 
        DEBUG2(VAR, "%s:delete %s\n", scope->name, varname);
        v = he->value;
+       if (v->inUse) {
+               Parse_Error(PARSE_FATAL,
+                   "Cannot delete variable \"%s\" while it is used.",
+                   v->name.str);
+               return;
+       }
        if (v->exported)
                unsetenv(v->name.str);
        if (strcmp(v->name.str, MAKE_EXPORTED) == 0)



Home | Main Index | Thread Index | Old Index