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.
This commit is contained in:
parent
05762b361e
commit
412424cefd
|
@ -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
|
||||
|
|
|
@ -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-indirect
|
|||
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
|
||||
|
|
|
@ -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
|
|
@ -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}'
|
|
@ -13,5 +13,4 @@ mod-loop-dollar:$3$:
|
|||
mod-loop-dollar:$${word}$$:
|
||||
mod-loop-dollar:$$5$$:
|
||||
mod-loop-dollar:$$${word}$$$:
|
||||
: all: ' rest of the value'
|
||||
exit status 0
|
||||
|
|
|
@ -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 @@ CMDLINE= global # needed for deleting the environment
|
|||
. 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}'
|
||||
|
|
|
@ -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 @@ Var_Delete(GNode *scope, const char *varname)
|
|||
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue