mksh memory corruption / segmentation fault

Bug #1440685 reported by Pawel Wylecial on 2015-04-06
258
This bug affects 1 person
Affects Status Importance Assigned to Milestone
mksh
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)

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

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.

Thorsten Glaser (mirabilos) wrote :

… ah sorry, I see you tried R50e.

Changed in mksh:
assignee: nobody → Thorsten Glaser (mirabilos)
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
Thorsten Glaser (mirabilos) wrote :

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

Changed in mksh:
status: Triaged → Fix Committed
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  Edit
Everyone can see this security related information.

Other bug subscribers