mksh memory corruption / segmentation fault

Bug #1440685 reported by Pawel Wylecial
258
This bug affects 1 person
Affects Status Importance Assigned to Milestone
mksh
Fix Released
Critical
Thorsten Glaser

Bug Description

Tested on the newest version @ Ubuntu (46-2) and compiled from source (mksh-R50e). Also tested on Android 5.0.1 with same results.
It seems to crash at exec.c:1415 in function iosetup() if (e->savefd[iop->unit] == 0) {

By manipulating the value on the left from '>' (works the same with '<), we can set values of EAX and EBP.

howl@overflow:~$ gdb -q /bin/mksh
Reading symbols from /bin/mksh...(no debugging symbols found)...done.
(gdb) r
Starting program: /bin/mksh
$ 1000200887800>1

Program received signal SIGSEGV, Segmentation fault.
0x80009c92 in ?? ()
(gdb) i r
eax 0xe09e5df8 -526492168
ecx 0x3 3
edx 0x0 0
ebx 0x8003be50 -2147238320
esp 0xbffff210 0xbffff210
ebp 0x41414344 0x41414344
esi 0x80044a54 -2147202476
edi 0x2 2
eip 0x80009c92 0x80009c92
eflags 0x10206 [ PF IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) bt
#0 0x80009c92 in ?? ()
Backtrace stopped: Cannot access memory at address 0x41414348
(gdb) info frame 0
Stack frame at 0x4141434c:
 eip = 0x80009c92;
    saved eip = <error: Cannot access memory at address 0x41414348>
 Outermost frame: Cannot access memory at address 0x41414348
 Arglist at 0x41414344, args:
 Locals at 0x41414344, Previous frame's sp is 0x4141434c
Cannot access memory at address 0x41414344
(gdb)

Revision history for this message
Pawel Wylecial (pawel-wylecial) wrote :

i have compiled mksh with asan, it normally gives the following results:
$ 1000200887800>1
ASAN:SIGSEGV
=================================================================
==7080== ERROR: AddressSanitizer: SEGV on unknown address 0x743ceb74 (pc 0x0806143e sp 0xbf9b1d20 bp 0xbf9b1eb8 T0)
AddressSanitizer can not provide additional info.
    #0 0x806143d (/home/howl/mksh/mksh/mksh+0x806143d)
==7080== ABORTING

or for the exact value that will give -1 on the left side expression:
$ 1112396529663>1
./mksh: can't finish (dup) redirection -1>1 Bad file descriptor
ASAN:SIGSEGV
=================================================================
==7052== ERROR: AddressSanitizer: SEGV on unknown address 0xffff0000 (pc 0x08049fbd sp 0xbfe9e710 bp 0xbfe9e738 T0)
AddressSanitizer can not provide additional info.
    #0 0x8049fbc (/home/howl/mksh/mksh/mksh+0x8049fbc)
==7052== ABORTING

but setting it for -3 gives the following result:
$ 1112396529661>1
=================================================================
==7057== ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb3002f7e at pc 0x806143e bp 0xbf989a68 sp 0xbf989a5c
READ of size 2 at 0xb3002f7e thread T0
    #0 0x806143d (/home/howl/mksh/mksh/mksh+0x806143d)
0xb3002f7e is located 2 bytes to the left of 116-byte region [0xb3002f80,0xb3002ff4)
allocated by thread T0 here:
    #0 0xb61b89b4 (/usr/lib/i386-linux-gnu/libasan.so.0.0.0+0x169b4)
    #1 0x8049d5a (/home/howl/mksh/mksh/mksh+0x8049d5a)
    #2 0x8049c29 (/home/howl/mksh/mksh/mksh+0x8049c29)
    #3 0x80589e0 (/home/howl/mksh/mksh/mksh+0x80589e0)
    #4 0x80a20b0 (/home/howl/mksh/mksh/mksh+0x80a20b0)
    #5 0x80a0dc3 (/home/howl/mksh/mksh/mksh+0x80a0dc3)
    #6 0xb600ca82 (/lib/i386-linux-gnu/libc-2.19.so+0x19a82)
Shadow bytes around the buggy address:
  0x36600590: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x366005a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x366005b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x366005c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x366005d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x366005e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa[fa]
  0x366005f0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 fa
  0x36600600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36600610: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36600620: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36600630: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable: 00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone: fa
  Heap righ redzone: fb
  Freed Heap region: fd
  Stack left redzone: f1
  Stack mid redzone: f2
  Stack right redzone: f3
  Stack partial redzone: f4
  Stack after return: f5
  Stack use after scope: f8
  Global redzone: f9
  Global init order: f6
  Poisoned by user: f7
  ASan internal: fe
==7057== ABORTING

Revision history for this message
Thorsten Glaser (mirabilos) wrote :

Huh, why didn't I get this as eMail? Only seeing it by accident…

mksh 46-2 is positively ancient, we're at R50e now.

Revision history for this message
Thorsten Glaser (mirabilos) wrote :

… ah sorry, I see you tried R50e.

Changed in mksh:
assignee: nobody → Thorsten Glaser (mirabilos)
Revision history for this message
Thorsten Glaser (mirabilos) wrote :

OK, I see it (although the crash does not happen on MirBSD like that, the corruption does for -1 at least).

I think the fix is:
• exec.c:iosetup() int u, plus globally iop->unit, must become unsigned (probably uint8_t, as the code in syn.c only allows for two decimal digits)
• the code in lex.c:918ff must be changed to have an upper bound; there is a check for FDBASE below, which is smaller than NUFILE, which is smaller than 100 and what e->savefd is allocated with

Funnily enough, e->savefd has members of type short, which can then probably also be changed to uint8_t? I think limiting mksh to only accept [0;100[ as fd numbers is reasonable, given the currently-existing code and situation.

Will work on it ASAP (but not any more tonight). Thank you very much for reporting!

Changed in mksh:
importance: Undecided → Critical
status: New → Triaged
Revision history for this message
Thorsten Glaser (mirabilos) wrote :

enh found that main.c around line 1460 needs to also be fixed.

Changed in mksh:
status: Triaged → Fix Committed
Revision history for this message
Thorsten Glaser (mirabilos) wrote :

mksh R50f was released with the fix, and it has been stewing in CVS HEAD for a while.

information type: Private Security → Public Security
Changed in mksh:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.