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}'