[Toybox] [PATCH] sh.c: fix memory corruption due to uninitialized sh_function in sh_run
Rich Felker
dalias at libc.org
Sat Jan 11 17:20:47 PST 2020
This code only happened to work due to being started on a pristine
zero-filled stack. With dynamic linking on i386/musl, I got:
Program received signal SIGSEGV, Segmentation fault.
0x08050fd1 in dlist_add_nomalloc (list=0xffffd9f0, new=0x80afef0) at lib/llist.c:90
90 (*list)->prev->next = new;
(gdb) bt
#0 0x08050fd1 in dlist_add_nomalloc (list=0xffffd9f0, new=0x80afef0) at lib/llist.c:90
#1 0x0806f913 in parse_line (line=line at entry=0x80a3aa0 "cd .", sp=sp at entry=0xffffd9ec) at toys/pending/sh.c:1142
#2 0x0807166d in sh_run (new=0x80a3aa0 "cd .") at toys/pending/sh.c:1693
#3 sh_main () at toys/pending/sh.c:1841
#4 0x080542ee in toy_exec_which (which=<optimized out>, argv=0xffffdba8) at main.c:175
#5 0x08054317 in toy_exec (argv=0xffffdba8) at main.c:182
#6 0x0805433f in toybox_main () at main.c:196
#7 0x080542ee in toy_exec_which (which=<optimized out>, argv=0xffffdba4) at main.c:175
#8 0x08054317 in toy_exec (argv=0xffffdba4) at main.c:182
#9 0x0805433f in toybox_main () at main.c:196
#10 0x0804c68f in main (argc=2, argv=0xffffdba4) at main.c:260
(gdb) print list
$1 = (struct double_list **) 0xffffd9f0
(gdb) print *list
$2 = (struct double_list *) 0xf7ffb1e0 <__stdout_FILE>
This was just what happened to be on the stack from before sh_run was
called, likely leftover from dynamic linker startup. With the attached
patch, it now runs without crashing.
Rich
-------------- next part --------------
>From 555871688b88dafd6d5b6f80bba7af01acfb8a7c Mon Sep 17 00:00:00 2001
From: Rich Felker <dalias at aerifal.cx>
Date: Sat, 11 Jan 2020 20:16:48 -0500
Subject: [PATCH] sh.c: fix memory corruption due to uninitialized sh_function
in sh_run
---
toys/pending/sh.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/toys/pending/sh.c b/toys/pending/sh.c
index 482639da..32e33507 100644
--- a/toys/pending/sh.c
+++ b/toys/pending/sh.c
@@ -1685,7 +1685,7 @@ dprintf(2, "TODO skipped running for((;;)), need math parser\n");
// Parse and run a self-contained command line with no prompt/continuation
static int sh_run(char *new)
{
- struct sh_function scratch;
+ struct sh_function scratch = { 0 };
int rc;
// TODO: parse with len? (End early?)
--
2.21.0
More information about the Toybox
mailing list