Fix buffer overflow in _rl_copy_to_kill_ring 51/200751/1 submit/tizen_base/20190509.002219
authorMikhail Kashkarov <m.kashkarov@partner.samsung.com>
Fri, 1 Mar 2019 16:09:44 +0000 (19:09 +0300)
committerMikhail Kashkarov <m.kashkarov@partner.samsung.com>
Fri, 1 Mar 2019 16:15:13 +0000 (19:15 +0300)
This fix is included in bash-5.0:

commit d233b485e83c3a784b803fb894280773f16f2deb (tag: bash-5.0)
Author: Chet Ramey <chet.ramey@case.edu>
Date:   Mon Jan 7 09:27:52 2019 -0500
...
lib/readline/kill.c
       - _rl_copy_to_kill_ring: make sure the current slot in the kill ring
         has something in it, even if the last command was a kill, before
         trying to modify it. Another fuzzing bug
...

Address Sanitizer report:

==12957==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x607000000700 at pc 0x561a0cc3482c bp 0x7fff4d983030 sp 0x7fff4d983028
READ of size 8 at 0x607000000700 thread T0
    #0 0x561a0cc3482b in _rl_copy_to_kill_ring /usr/src/debug/bash-3.2.57/lib/readline/kill.c:120:0
    #1 0x561a0cc350a8 in rl_kill_text /usr/src/debug/bash-3.2.57/lib/readline/kill.c:183:0
    #2 0x561a0cc3519e in rl_backward_kill_word /usr/src/debug/bash-3.2.57/lib/readline/kill.c:238:0
    #3 0x561a0cc0794a in _rl_dispatch_subseq /usr/src/debug/bash-3.2.57/lib/readline/readline.c:742:0
    #4 0x561a0cc07c18 in _rl_dispatch_subseq /usr/src/debug/bash-3.2.57/lib/readline/readline.c:831:0
    #5 0x561a0cc08007 in readline_internal_char /usr/src/debug/bash-3.2.57/lib/readline/readline.c:519:0
    #6 0x561a0cc08cb4 in readline_internal_charloop /usr/src/debug/bash-3.2.57/lib/readline/readline.c:545:0
    #7 0x561a0cc08cb4 in readline_internal /usr/src/debug/bash-3.2.57/lib/readline/readline.c:559:0
    #8 0x561a0cc08cb4 in readline /usr/src/debug/bash-3.2.57/lib/readline/readline.c:321:0
    #9 0x561a0cb2fa21 in yy_readline_get /usr/src/debug/bash-3.2.57/./parse.y:1218:0
    #10 0x561a0cb3449b in yy_getc /usr/src/debug/bash-3.2.57/./parse.y:1151:0
    #11 0x561a0cb3449b in shell_getc /usr/src/debug/bash-3.2.57/./parse.y:1947:0
    #12 0x561a0cb372e0 in read_token /usr/src/debug/bash-3.2.57/./parse.y:2594:0
    #13 0x561a0cb3c05a in yylex /usr/src/debug/bash-3.2.57/./parse.y:2223:0
    #14 0x561a0cb3dd7a in yyparse /usr/src/debug/bash-3.2.57/y.tab.c:5133:0
    #15 0x561a0cb2e6a1 in parse_command /usr/src/debug/bash-3.2.57/eval.c:222:0
    #16 0x561a0cb2e8cc in read_command /usr/src/debug/bash-3.2.57/eval.c:266:0
    #17 0x561a0cb2ee45 in reader_loop /usr/src/debug/bash-3.2.57/eval.c:132:0
    #18 0x561a0cb2b537 in main /usr/src/debug/bash-3.2.57/shell.c:715:0
    #19 0x7fda249d71f0 in __libc_start_main /usr/src/debug/glibc-2.24/csu/../csu/libc-start.c:289:0
    #20 0x561a0cb2d059 in ?? /usr/src/debug//////////////glibc-2.24/csu/../sysdeps/x86_64/start.S:120:0 (/emul/usr/bin/bash+0x6f059)

0x607000000700 is located 0 bytes to the right of 80-byte region [0x6070000006b0,0x607000000700)
allocated by thread T0 here:
    #0 0x7fda25043790 in __interceptor_realloc _asan_rtl_:0
    #1 0x561a0cbd01a3 in xrealloc /usr/src/debug/bash-3.2.57/xmalloc.c:109:0
    #2 0x561a0cc3458d in _rl_copy_to_kill_ring /usr/src/debug/bash-3.2.57/lib/readline/kill.c:125:0
    #3 0x561a0cc350a8 in rl_kill_text /usr/src/debug/bash-3.2.57/lib/readline/kill.c:183:0
    #4 0x561a0cc3519e in rl_backward_kill_word /usr/src/debug/bash-3.2.57/lib/readline/kill.c:238:0
    #5 0x561a0cc0794a in _rl_dispatch_subseq /usr/src/debug/bash-3.2.57/lib/readline/readline.c:742:0
    #6 0x561a0cc07c18 in _rl_dispatch_subseq /usr/src/debug/bash-3.2.57/lib/readline/readline.c:831:0
    #7 0x561a0cc08007 in readline_internal_char /usr/src/debug/bash-3.2.57/lib/readline/readline.c:519:0
    #8 0x561a0cc08cb4 in readline_internal_charloop /usr/src/debug/bash-3.2.57/lib/readline/readline.c:545:0
    #9 0x561a0cc08cb4 in readline_internal /usr/src/debug/bash-3.2.57/lib/readline/readline.c:559:0
    #10 0x561a0cc08cb4 in readline /usr/src/debug/bash-3.2.57/lib/readline/readline.c:321:0
    #11 0x561a0cb2fa21 in yy_readline_get /usr/src/debug/bash-3.2.57/./parse.y:1218:0
    #12 0x561a0cb3449b in yy_getc /usr/src/debug/bash-3.2.57/./parse.y:1151:0
    #13 0x561a0cb3449b in shell_getc /usr/src/debug/bash-3.2.57/./parse.y:1947:0
    #14 0x561a0cb372e0 in read_token /usr/src/debug/bash-3.2.57/./parse.y:2594:0
    #15 0x561a0cb3c05a in yylex /usr/src/debug/bash-3.2.57/./parse.y:2223:0
    #16 0x561a0cb3dd7a in yyparse /usr/src/debug/bash-3.2.57/y.tab.c:5133:0
    #17 0x561a0cb2e6a1 in parse_command /usr/src/debug/bash-3.2.57/eval.c:222:0
    #18 0x561a0cb2e8cc in read_command /usr/src/debug/bash-3.2.57/eval.c:266:0
    #19 0x561a0cb2ee45 in reader_loop /usr/src/debug/bash-3.2.57/eval.c:132:0
    #20 0x561a0cb2b537 in main /usr/src/debug/bash-3.2.57/shell.c:715:0
    #21 0x7fda249d71f0 in __libc_start_main /usr/src/debug/glibc-2.24/csu/../csu/libc-start.c:289:0

SUMMARY: AddressSanitizer: heap-buffer-overflow (/emul/usr/bin/bash+0x17682b)
Shadow bytes around the buggy address:
  0x0c0e7fff8090: 00 00 00 00 00 00 00 00 00 fa fa fa fa fa 00 00
  0x0c0e7fff80a0: 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa fa
  0x0c0e7fff80b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff80c0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c0e7fff80d0: fd fa fa fa fa fa 00 00 00 00 00 00 00 00 00 00
=>0x0c0e7fff80e0:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff80f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff8100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff8110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff8120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff8130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

Change-Id: If4281b0aea13a411c7bf327656f4f34ab79500b0

lib/readline/kill.c

index 031ddf47c5ba12fab87f91edaff594dfd02c85a1..cf34e9561fea9ae8cfa634fed40da94fa9a10ca3 100644 (file)
@@ -122,7 +122,7 @@ _rl_copy_to_kill_ring (text, append)
          else
            {
              slot = rl_kill_ring_length += 1;
-             rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *));
+             rl_kill_ring = (char **)xrealloc (rl_kill_ring, (slot + 1) * sizeof (char *));
            }
          rl_kill_ring[--slot] = (char *)NULL;
        }
@@ -131,7 +131,7 @@ _rl_copy_to_kill_ring (text, append)
     slot = rl_kill_ring_length - 1;
 
   /* If the last command was a kill, prepend or append. */
-  if (_rl_last_command_was_kill && rl_editing_mode != vi_mode)
+  if (_rl_last_command_was_kill && rl_kill_ring[slot] && rl_editing_mode != vi_mode)
     {
       old = rl_kill_ring[slot];
       new = (char *)xmalloc (1 + strlen (old) + strlen (text));