[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