aboutsummaryrefslogtreecommitdiffstats
path: root/usr/gen_init_cpio.c
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2012-10-25 16:38:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-25 17:37:53 -0400
commit20f1de659b77364d55d4e7fad2ef657e7730323f (patch)
tree397b5a643fbcdf6cbb5bf69fb5ead4160db3716b /usr/gen_init_cpio.c
parentfee0de7791f967c2c5f0d43eb7b7261761b45e64 (diff)
gen_init_cpio: avoid stack overflow when expanding
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> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'usr/gen_init_cpio.c')
-rw-r--r--usr/gen_init_cpio.c43
1 files changed, 23 insertions, 20 deletions
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
index af0f22fb1ef7..aca6edcbbc6f 100644
--- a/usr/gen_init_cpio.c
+++ b/usr/gen_init_cpio.c
@@ -303,7 +303,7 @@ static int cpio_mkfile(const char *name, const char *location,
303 int retval; 303 int retval;
304 int rc = -1; 304 int rc = -1;
305 int namesize; 305 int namesize;
306 int i; 306 unsigned int i;
307 307
308 mode |= S_IFREG; 308 mode |= S_IFREG;
309 309
@@ -381,25 +381,28 @@ error:
381 381
382static char *cpio_replace_env(char *new_location) 382static char *cpio_replace_env(char *new_location)
383{ 383{
384 char expanded[PATH_MAX + 1]; 384 char expanded[PATH_MAX + 1];
385 char env_var[PATH_MAX + 1]; 385 char env_var[PATH_MAX + 1];
386 char *start; 386 char *start;
387 char *end; 387 char *end;
388 388
389 for (start = NULL; (start = strstr(new_location, "${")); ) { 389 for (start = NULL; (start = strstr(new_location, "${")); ) {
390 end = strchr(start, '}'); 390 end = strchr(start, '}');
391 if (start < end) { 391 if (start < end) {
392 *env_var = *expanded = '\0'; 392 *env_var = *expanded = '\0';
393 strncat(env_var, start + 2, end - start - 2); 393 strncat(env_var, start + 2, end - start - 2);
394 strncat(expanded, new_location, start - new_location); 394 strncat(expanded, new_location, start - new_location);
395 strncat(expanded, getenv(env_var), PATH_MAX); 395 strncat(expanded, getenv(env_var),
396 strncat(expanded, end + 1, PATH_MAX); 396 PATH_MAX - strlen(expanded));
397 strncpy(new_location, expanded, PATH_MAX); 397 strncat(expanded, end + 1,
398 } else 398 PATH_MAX - strlen(expanded));
399 break; 399 strncpy(new_location, expanded, PATH_MAX);
400 } 400 new_location[PATH_MAX] = 0;
401 401 } else
402 return new_location; 402 break;
403 }
404
405 return new_location;
403} 406}
404 407
405 408