mirror of
https://github.com/mirror/make.git
synced 2025-03-23 00:00:32 +08:00
[SV 64124] Avoid use-after-free in expand_variable_buf()
When the expanded value of the variable in buf occupies more space than available in variable_buffer, function variable_buffer_output reallocates variable_buffer: return a pointer into the new memory, not the old memory. * src/expand.c (expand_variable_buf): Preserve the offset of buf and return that offset into the (potentially reallocated) buffer. * tests/scripts/features/expand: Add tests.
This commit is contained in:
parent
ebe0a1c9f1
commit
06c75a35b9
16
src/expand.c
16
src/expand.c
@ -255,17 +255,27 @@ expand_variable_output (char *ptr, const char *name, size_t length)
|
|||||||
/* Expand a simple reference to variable NAME, which is LENGTH chars long.
|
/* Expand a simple reference to variable NAME, which is LENGTH chars long.
|
||||||
The result is written to BUF which must point into the variable_buffer.
|
The result is written to BUF which must point into the variable_buffer.
|
||||||
If BUF is NULL, start at the beginning of the current variable_buffer.
|
If BUF is NULL, start at the beginning of the current variable_buffer.
|
||||||
Returns BUF, or the beginning of the buffer if BUF is NULL. */
|
Returns a pointer to the START of the expanded value of the variable.
|
||||||
|
The returned value is located inside variable_buffer.
|
||||||
|
The returned value is valid until the next call to one of the functions
|
||||||
|
which use variable_buffer. expand_variable_buf may reallocate
|
||||||
|
variable_buffer and render the passed-in BUF invalid. */
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
expand_variable_buf (char *buf, const char *name, size_t length)
|
expand_variable_buf (char *buf, const char *name, size_t length)
|
||||||
{
|
{
|
||||||
|
size_t offs;
|
||||||
|
|
||||||
if (!buf)
|
if (!buf)
|
||||||
buf = initialize_variable_output ();
|
buf = initialize_variable_output ();
|
||||||
|
|
||||||
expand_variable_output (buf, name, length);
|
assert (buf >= variable_buffer);
|
||||||
|
assert (buf < variable_buffer + variable_buffer_length);
|
||||||
|
offs = buf - variable_buffer;
|
||||||
|
|
||||||
return buf;
|
expand_variable_output (buf, name, length);
|
||||||
|
return variable_buffer + offs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expand a simple reference to variable NAME, which is LENGTH chars long.
|
/* Expand a simple reference to variable NAME, which is LENGTH chars long.
|
||||||
|
26
tests/scripts/features/expand
Normal file
26
tests/scripts/features/expand
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# -*-perl-*-
|
||||||
|
|
||||||
|
$description = "Test variable expansion.";
|
||||||
|
|
||||||
|
# sv 64124.
|
||||||
|
# Expand a variable whose value exceeds 200 bytes.
|
||||||
|
# 200 is the initial size of variable_buffer.
|
||||||
|
# Value bigger than 200 bytes causes a realloc of variable_buffer.
|
||||||
|
# In this test the variable being expanded is MAKEFLAGS and its value occupies
|
||||||
|
# 11, 550 and 110000 bytes.
|
||||||
|
|
||||||
|
my $s = "hello_world";
|
||||||
|
my @mult = (1, 50, 10000);
|
||||||
|
|
||||||
|
for my $m (@mult) {
|
||||||
|
my $answer = $s x $m;
|
||||||
|
$ENV{'MAKEFLAGS'} = " -- hello=$answer";
|
||||||
|
run_make_test(q!
|
||||||
|
$(info x$(hello)y)
|
||||||
|
all:
|
||||||
|
!,
|
||||||
|
'', "x${answer}y\n#MAKE#: Nothing to be done for 'all'.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
# This tells the test driver that the perl test script executed properly.
|
||||||
|
1;
|
Loading…
Reference in New Issue
Block a user