diff options
author | Dmitry Goncharov <dgoncharov@users.sf.net> | 2023-04-30 09:39:04 -0400 |
---|---|---|
committer | Paul Smith <psmith@gnu.org> | 2023-04-30 09:41:02 -0400 |
commit | 06c75a35b93ac6ceacf0474e8b3a23d494fcea07 (patch) | |
tree | 3895563959fcc5e3f10bf58e091aea5b4ac2b3ec /src | |
parent | ebe0a1c9f1d1529a3f2c64d628686f500d460b0e (diff) | |
download | make-git-06c75a35b93ac6ceacf0474e8b3a23d494fcea07.tar.gz |
[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.
Diffstat (limited to 'src')
-rw-r--r-- | src/expand.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/src/expand.c b/src/expand.c index 3c97f387..3ca59505 100644 --- a/src/expand.c +++ b/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. 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. - 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 * expand_variable_buf (char *buf, const char *name, size_t length) { + size_t offs; + if (!buf) 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. |