Module Name:    src
Committed By:   rillig
Date:           Sun Dec  5 15:01:04 UTC 2021

Modified Files:
        src/usr.bin/make/unit-tests: varmod-loop-varname.exp
            varmod-loop-varname.mk varmod-loop.exp varmod-loop.mk

Log Message:
tests/make: demonstrate use-after-free in modifier ':@'


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/usr.bin/make/unit-tests/varmod-loop-varname.exp \
    src/usr.bin/make/unit-tests/varmod-loop-varname.mk
cvs rdiff -u -r1.11 -r1.12 src/usr.bin/make/unit-tests/varmod-loop.exp
cvs rdiff -u -r1.16 -r1.17 src/usr.bin/make/unit-tests/varmod-loop.mk

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/unit-tests/varmod-loop-varname.exp
diff -u src/usr.bin/make/unit-tests/varmod-loop-varname.exp:1.3 src/usr.bin/make/unit-tests/varmod-loop-varname.exp:1.4
--- src/usr.bin/make/unit-tests/varmod-loop-varname.exp:1.3	Tue Nov 30 23:52:19 2021
+++ src/usr.bin/make/unit-tests/varmod-loop-varname.exp	Sun Dec  5 15:01:04 2021
@@ -1,11 +1,11 @@
 make: "varmod-loop-varname.mk" line 16: In the :@ modifier of "", the variable name "${:Ubar:S,b,v,}" must not contain a dollar.
 make: "varmod-loop-varname.mk" line 16: Malformed conditional (${:Uone two three:@${:Ubar:S,b,v,}@+${var}+@} != "+one+ +two+ +three+")
-make: "varmod-loop-varname.mk" line 83: In the :@ modifier of "1 2 3", the variable name "v$" must not contain a dollar.
-make: "varmod-loop-varname.mk" line 83: Malformed conditional (${1 2 3:L:@v$@($v)@} != "(1) (2) (3)")
-make: "varmod-loop-varname.mk" line 88: In the :@ modifier of "1 2 3", the variable name "v$$" must not contain a dollar.
-make: "varmod-loop-varname.mk" line 88: Malformed conditional (${1 2 3:L:@v$$@($v)@} != "() () ()")
-make: "varmod-loop-varname.mk" line 93: In the :@ modifier of "1 2 3", the variable name "v$$$" must not contain a dollar.
-make: "varmod-loop-varname.mk" line 93: Malformed conditional (${1 2 3:L:@v$$$@($v)@} != "() () ()")
+make: "varmod-loop-varname.mk" line 85: In the :@ modifier of "1 2 3", the variable name "v$" must not contain a dollar.
+make: "varmod-loop-varname.mk" line 85: Malformed conditional (${1 2 3:L:@v$@($v)@} != "(1) (2) (3)")
+make: "varmod-loop-varname.mk" line 90: In the :@ modifier of "1 2 3", the variable name "v$$" must not contain a dollar.
+make: "varmod-loop-varname.mk" line 90: Malformed conditional (${1 2 3:L:@v$$@($v)@} != "() () ()")
+make: "varmod-loop-varname.mk" line 95: In the :@ modifier of "1 2 3", the variable name "v$$$" must not contain a dollar.
+make: "varmod-loop-varname.mk" line 95: Malformed conditional (${1 2 3:L:@v$$$@($v)@} != "() () ()")
 make: Fatal errors encountered -- cannot continue
 make: stopped in unit-tests
 exit status 1
Index: src/usr.bin/make/unit-tests/varmod-loop-varname.mk
diff -u src/usr.bin/make/unit-tests/varmod-loop-varname.mk:1.3 src/usr.bin/make/unit-tests/varmod-loop-varname.mk:1.4
--- src/usr.bin/make/unit-tests/varmod-loop-varname.mk:1.3	Tue Nov 30 23:52:19 2021
+++ src/usr.bin/make/unit-tests/varmod-loop-varname.mk	Sun Dec  5 15:01:04 2021
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-loop-varname.mk,v 1.3 2021/11/30 23:52:19 rillig Exp $
+# $NetBSD: varmod-loop-varname.mk,v 1.4 2021/12/05 15:01:04 rillig Exp $
 #
 # Tests for the first part of the variable modifier ':@var@...@', which
 # contains the variable name to use during the loop.
@@ -15,6 +15,8 @@
 # variable name.
 .if ${:Uone two three:@${:Ubar:S,b,v,}@+${var}+@} != "+one+ +two+ +three+"
 .  error
+.else
+.  error
 .endif
 
 

Index: src/usr.bin/make/unit-tests/varmod-loop.exp
diff -u src/usr.bin/make/unit-tests/varmod-loop.exp:1.11 src/usr.bin/make/unit-tests/varmod-loop.exp:1.12
--- src/usr.bin/make/unit-tests/varmod-loop.exp:1.11	Tue Nov 30 23:52:19 2021
+++ src/usr.bin/make/unit-tests/varmod-loop.exp	Sun Dec  5 15:01:04 2021
@@ -13,4 +13,5 @@ mod-loop-dollar:$3$:
 mod-loop-dollar:$${word}$$:
 mod-loop-dollar:$$5$$:
 mod-loop-dollar:$$${word}$$$:
+: all: ' rest of the value'
 exit status 0

Index: src/usr.bin/make/unit-tests/varmod-loop.mk
diff -u src/usr.bin/make/unit-tests/varmod-loop.mk:1.16 src/usr.bin/make/unit-tests/varmod-loop.mk:1.17
--- src/usr.bin/make/unit-tests/varmod-loop.mk:1.16	Tue Nov 30 23:52:19 2021
+++ src/usr.bin/make/unit-tests/varmod-loop.mk	Sun Dec  5 15:01:04 2021
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-loop.mk,v 1.16 2021/11/30 23:52:19 rillig Exp $
+# $NetBSD: varmod-loop.mk,v 1.17 2021/12/05 15:01:04 rillig Exp $
 #
 # Tests for the :@var@...${var}...@ variable modifier.
 
@@ -187,6 +187,31 @@ CMDLINE=	global		# needed for deleting t
 .endif
 
 
-# TODO: Actually trigger the undefined behavior (use after free) that was
-#  already suspected in Var_Parse, in the comment 'the value of the variable
-#  must not change'.
+# 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}'

Reply via email to