mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 17:25:38 +00:00
gen_init_cpio: avoid stack overflow when expanding
commit 20f1de659b
upstream.
Fix possible overflow of the buffer used for expanding environment
variables when building file list.
In the extremely unlikely case of an attacker having control over the
environment variables visible to gen_init_cpio, control over the
contents of the file gen_init_cpio parses, and gen_init_cpio was built
without compiler hardening, the attacker can gain arbitrary execution
control via a stack buffer overflow.
$ cat usr/crash.list
file foo ${BIG}${BIG}${BIG}${BIG}${BIG}${BIG} 0755 0 0
$ BIG=$(perl -e 'print "A" x 4096;') ./usr/gen_init_cpio usr/crash.list
*** buffer overflow detected ***: ./usr/gen_init_cpio terminated
This also replaces the space-indenting with tabs.
Patch based on existing fix extracted from grsecurity.
Signed-off-by: Kees Cook <keescook@chromium.org>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Brad Spengler <spender@grsecurity.net>
Cc: PaX Team <pageexec@freemail.hu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w@1wt.eu>
This commit is contained in:
parent
56fb3d90a3
commit
dbd3462bbd
@ -299,7 +299,7 @@ static int cpio_mkfile(const char *name, const char *location,
|
||||
int retval;
|
||||
int rc = -1;
|
||||
int namesize;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
mode |= S_IFREG;
|
||||
|
||||
@ -372,25 +372,28 @@ static int cpio_mkfile(const char *name, const char *location,
|
||||
|
||||
static char *cpio_replace_env(char *new_location)
|
||||
{
|
||||
char expanded[PATH_MAX + 1];
|
||||
char env_var[PATH_MAX + 1];
|
||||
char *start;
|
||||
char *end;
|
||||
char expanded[PATH_MAX + 1];
|
||||
char env_var[PATH_MAX + 1];
|
||||
char *start;
|
||||
char *end;
|
||||
|
||||
for (start = NULL; (start = strstr(new_location, "${")); ) {
|
||||
end = strchr(start, '}');
|
||||
if (start < end) {
|
||||
*env_var = *expanded = '\0';
|
||||
strncat(env_var, start + 2, end - start - 2);
|
||||
strncat(expanded, new_location, start - new_location);
|
||||
strncat(expanded, getenv(env_var), PATH_MAX);
|
||||
strncat(expanded, end + 1, PATH_MAX);
|
||||
strncpy(new_location, expanded, PATH_MAX);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
for (start = NULL; (start = strstr(new_location, "${")); ) {
|
||||
end = strchr(start, '}');
|
||||
if (start < end) {
|
||||
*env_var = *expanded = '\0';
|
||||
strncat(env_var, start + 2, end - start - 2);
|
||||
strncat(expanded, new_location, start - new_location);
|
||||
strncat(expanded, getenv(env_var),
|
||||
PATH_MAX - strlen(expanded));
|
||||
strncat(expanded, end + 1,
|
||||
PATH_MAX - strlen(expanded));
|
||||
strncpy(new_location, expanded, PATH_MAX);
|
||||
new_location[PATH_MAX] = 0;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
return new_location;
|
||||
return new_location;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user