Discussion:
expand_prompt_string segmentation faults
Eduardo A. Bustamante López
2018-09-14 07:26:55 UTC
Permalink
Found the following two cases by fuzzing with AFL:

# Case #1: array_expand_index
bash <<'EOF'
x='${p[--b[?]]'; echo ${***@P}
EOF

# Case #1 backtrace
: <<'EOF'
Program received signal SIGSEGV, Segmentation fault.
0x000000000080e0d3 in __strchr_sse2 ()
#0 0x000000000080e0d3 in __strchr_sse2 ()
#1 0x00000000006d954b in mbschr (s=0x0, c=91) at mbschr.c:90
#2 0x000000000058acdf in valid_array_reference (name=0x0, flags=0) at arrayfunc.c:899
#3 0x000000000049c4e9 in bind_int_variable (lhs=0x0, rhs=0xbb5228 "-1", flags=0) at variables.c:3371
#4 0x00000000004c632c in expr_bind_variable (lhs=0x0, rhs=<optimized out>) at expr.c:333
#5 exp0 () at expr.c:1015
#6 exp1 () at expr.c:983
#7 0x00000000004c54ae in exppower () at expr.c:938
#8 0x00000000004c4cf8 in exp2 () at expr.c:863
#9 0x00000000004c4695 in exp3 () at expr.c:837
#10 expshift () at expr.c:813
#11 0x00000000004c3d95 in exp4 () at expr.c:783
#12 exp5 () at expr.c:761
#13 0x00000000004c3a61 in expband () at expr.c:743
#14 expbxor () at expr.c:724
#15 0x00000000004c3621 in expbor () at expr.c:705
#16 expland () at expr.c:678
#17 0x00000000004c2e01 in explor () at expr.c:650
#18 expcond () at expr.c:603
#19 0x00000000004c1f2b in expassign () at expr.c:488
#20 0x00000000004be48e in expcomma () at expr.c:472
#21 subexpr (expr=0xbc9a48 "--b[?]") at expr.c:450
#22 0x00000000004bdba0 in evalexp (expr=0xbc9a48 "--b[?]", flags=<optimized out>, validp=0x7fffffffce14) at expr.c:415
#23 0x0000000000589d81 in array_expand_index (var=<optimized out>, s=<optimized out>, len=<optimized out>, flags=<optimized out>) at arrayfunc.c:952
#24 0x000000000058b7f5 in array_value_internal (s=0xbc9a08 "p[--b[?]]", quoted=<optimized out>, flags=1, rtype=0x7fffffffce9c, indp=<optimized out>) at arrayfunc.c:1133
#25 0x000000000053eed1 in parameter_brace_expand_word (name=0xbc9a08 "p[--b[?]]", var_is_special=0, quoted=1, pflags=<optimized out>, indp=0x7fffffffcf40) at subst.c:6584
#26 0x0000000000536c7b in parameter_brace_expand (string=<optimized out>, quoted=<optimized out>, pflags=<optimized out>, contains_dollar_at=<optimized out>, indexp=<optimized out>, quoted_dollar_atp=<optimized out>) at subst.c:8702
#27 param_expand (string=0xbc5fe8 "${p[--b[?]]", sindex=<optimized out>, quoted=<optimized out>, expanded_something=<optimized out>, contains_dollar_at=<optimized out>, quoted_dollar_at_p=<optimized out>, had_quoted_null_p=0x0, pflags=<optimized out>) at subst.c:9316
#28 0x0000000000510893 in expand_word_internal (word=0x7fffffffd0b0, quoted=<optimized out>, isexp=<optimized out>, contains_dollar_at=<optimized out>, expanded_something=<optimized out>) at subst.c:9887
#29 0x000000000050f595 in expand_prompt_string (string=0xbc7ec8 "${p[--b[?]]", quoted=1, wflags=<optimized out>) at subst.c:3804
#30 0x0000000000420e71 in decode_prompt_string (string=<optimized out>) at ./parse.y:6065
#31 0x000000000055059c in string_transform (xc=<optimized out>, v=0xbc7dc8, s=0xbc5fc8 "${p[--b[?]]") at subst.c:7468
#32 0x000000000054a2b5 in parameter_brace_transform (varname=<optimized out>, value=<optimized out>, ind=<optimized out>, xform=<optimized out>, rtype=0, quoted=<optimized out>, pflags=0, flags=<optimized out>) at subst.c:7616
#33 0x000000000053bb17 in parameter_brace_expand (string=<optimized out>, quoted=<optimized out>, pflags=<optimized out>, contains_dollar_at=<optimized out>, indexp=<optimized out>, quoted_dollar_atp=<optimized out>) at subst.c:8884
#34 param_expand (string=0xbc7e68 "${***@P}", sindex=<optimized out>, quoted=<optimized out>, expanded_something=<optimized out>, contains_dollar_at=<optimized out>, quoted_dollar_at_p=<optimized out>, had_quoted_null_p=<optimized out>, pflags=<optimized out>) at subst.c:9316
#35 0x0000000000510893 in expand_word_internal (word=0xbc7828, quoted=<optimized out>, isexp=<optimized out>, contains_dollar_at=<optimized out>, expanded_something=<optimized out>) at subst.c:9887
#36 0x0000000000529560 in shell_expand_word_list (tlist=<optimized out>, eflags=0) at subst.c:11233
#37 expand_word_list_internal (list=<optimized out>, eflags=<optimized out>) at subst.c:11357
#38 0x000000000046f341 in execute_simple_command (simple_command=<optimized out>, pipe_in=-1, pipe_out=-1, async=<optimized out>, fds_to_close=<optimized out>) at execute_cmd.c:4278
#39 execute_command_internal (command=<optimized out>, asynchronous=<optimized out>, pipe_in=<optimized out>, pipe_out=<optimized out>, fds_to_close=<optimized out>) at execute_cmd.c:840
#40 0x000000000046b5cb in execute_connection (command=<optimized out>, asynchronous=<optimized out>, pipe_in=<optimized out>, pipe_out=<optimized out>, fds_to_close=<optimized out>) at execute_cmd.c:2689
#41 execute_command_internal (command=0xbc5e48, asynchronous=<optimized out>, pipe_in=<optimized out>, pipe_out=<optimized out>, fds_to_close=<optimized out>) at execute_cmd.c:1013
#42 0x0000000000605bcc in parse_and_execute (string=<optimized out>, from_file=<optimized out>, flags=4) at evalstring.c:436
#43 0x0000000000409a8c in run_one_command (command=<optimized out>) at shell.c:1416
#44 0x00000000004063a7 in main (argc=<optimized out>, argv=<optimized out>, env=<optimized out>) at shell.c:735
EOF

# Case #2
bash <<'EOF'
x='$[++K[+]]/'; echo ${***@P}
EOF

# Case #2 backtrace
: <<'EOF'
Program received signal SIGSEGV, Segmentation fault.
0x000000000080e0d3 in __strchr_sse2 ()
#0 0x000000000080e0d3 in __strchr_sse2 ()
#1 0x00000000006d954b in mbschr (s=0x0, c=91) at mbschr.c:90
#2 0x000000000058acdf in valid_array_reference (name=0x0, flags=0) at arrayfunc.c:899
#3 0x000000000049c4e9 in bind_int_variable (lhs=0x0, rhs=0xbb5248 "1", flags=0) at variables.c:3371
#4 0x00000000004c632c in expr_bind_variable (lhs=0x0, rhs=<optimized out>) at expr.c:333
#5 exp0 () at expr.c:1015
#6 exp1 () at expr.c:983
#7 0x00000000004c54ae in exppower () at expr.c:938
#8 0x00000000004c4cf8 in exp2 () at expr.c:863
#9 0x00000000004c4695 in exp3 () at expr.c:837
#10 expshift () at expr.c:813
#11 0x00000000004c3d95 in exp4 () at expr.c:783
#12 exp5 () at expr.c:761
#13 0x00000000004c3a61 in expband () at expr.c:743
#14 expbxor () at expr.c:724
#15 0x00000000004c3621 in expbor () at expr.c:705
#16 expland () at expr.c:678
#17 0x00000000004c2e01 in explor () at expr.c:650
#18 expcond () at expr.c:603
#19 0x00000000004c1f2b in expassign () at expr.c:488
#20 0x00000000004be48e in expcomma () at expr.c:472
#21 subexpr (expr=0xbcc9a8 "++K[+]") at expr.c:450
#22 0x00000000004bdba0 in evalexp (expr=0xbcc9a8 "++K[+]", flags=<optimized out>, validp=0x7fffffffdee0) at expr.c:415
#23 0x0000000000531828 in param_expand (string=0xbcc968 "$[++K[+]]/", sindex=<optimized out>, quoted=<optimized out>, expanded_something=<optimized out>, contains_dollar_at=<optimized out>, quoted_dollar_at_p=<optimized out>, had_quoted_null_p=0x0, pflags=<optimized out>) at subst.c:9391
#24 0x0000000000510893 in expand_word_internal (word=0x7fffffffe050, quoted=<optimized out>, isexp=<optimized out>, contains_dollar_at=<optimized out>, expanded_something=<optimized out>) at subst.c:9887
#25 0x000000000050f595 in expand_prompt_string (string=0xbcc948 "$[++K[+]]/", quoted=0, wflags=<optimized out>) at subst.c:3804
#26 0x00000000005b82a8 in bash_directory_completion_hook (dirname=0xb182f8 <rl_filename_completion_function.dirname>) at bashline.c:3284
#27 0x00000000007057c7 in rl_filename_completion_function (text=<optimized out>, state=<optimized out>) at complete.c:2508
#28 0x000000000070bacd in rl_completion_matches (text=0xbcc8c8 "$[++K[+]]/", entry_function=0x7051c0 <rl_filename_completion_function>) at complete.c:2185
#29 0x000000000070819f in gen_completion_matches (text=0xbcc8c8 "$[++K[+]]/", start=<optimized out>, end=<optimized out>, our_func=0x7051c0 <rl_filename_completion_function>, found_quote=<optimized out>, quote_char=<optimized out>) at complete.c:1228
#30 0x00000000006fd828 in rl_complete_internal (what_to_do=9) at complete.c:2013
#31 0x00000000006de509 in _rl_dispatch_subseq (key=9, map=0xb104d0 <vi_insertion_keymap>, got_subseq=0) at readline.c:852
#32 0x00000000006dc6ce in _rl_dispatch (key=0, map=0x5b) at readline.c:798
#33 readline_internal_char () at readline.c:632
#34 0x00000000006da72d in readline_internal_charloop () at readline.c:659
#35 readline_internal () at readline.c:671
#36 readline (prompt=0x8e11cf "") at readline.c:377
#37 0x0000000000629741 in edit_line (p=<optimized out>, itext=<optimized out>) at ./read.def:1104
#38 read_builtin (list=<optimized out>) at ./read.def:563
#39 0x0000000000483417 in execute_builtin (builtin=0x6268c0 <read_builtin>, words=<optimized out>, flags=<optimized out>, subshell=0) at execute_cmd.c:4677
#40 0x00000000004725d4 in execute_builtin_or_function (redirects=<optimized out>, fds_to_close=<optimized out>, flags=<optimized out>, words=<optimized out>, builtin=<optimized out>, var=<optimized out>) at execute_cmd.c:5185
#41 execute_simple_command (simple_command=<optimized out>, pipe_in=<optimized out>, pipe_out=<optimized out>, async=<optimized out>, fds_to_close=<optimized out>) at execute_cmd.c:4449
#42 execute_command_internal (command=<optimized out>, asynchronous=<optimized out>, pipe_in=<optimized out>, pipe_out=<optimized out>, fds_to_close=<optimized out>) at execute_cmd.c:840
#43 0x000000000046b5cb in execute_connection (command=<optimized out>, asynchronous=<optimized out>, pipe_in=<optimized out>, pipe_out=<optimized out>, fds_to_close=<optimized out>) at execute_cmd.c:2689
#44 execute_command_internal (command=0xbc5d88, asynchronous=<optimized out>, pipe_in=<optimized out>, pipe_out=<optimized out>, fds_to_close=<optimized out>) at execute_cmd.c:1013
#45 0x0000000000605bcc in parse_and_execute (string=<optimized out>, from_file=<optimized out>, flags=4) at evalstring.c:436
#46 0x0000000000409a8c in run_one_command (command=<optimized out>) at shell.c:1416
#47 0x00000000004063a7 in main (argc=<optimized out>, argv=<optimized out>, env=<optimized out>) at shell.c:735
EOF
Chet Ramey
2018-09-16 02:59:32 UTC
Permalink
Thanks for the report. They are the same problem.

Chet
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU ***@case.edu http://tiswww.cwru.edu/~chet/
Eduardo Bustamante
2018-09-16 06:55:21 UTC
Permalink
On Sat, Sep 15, 2018 at 8:15 PM Chet Ramey <***@case.edu> wrote:
(...)
Post by Chet Ramey
Thanks for the report. They are the same problem.
Thanks Chet. Do you have a patch for the issue? I have a few other
cases but I'm not sure if they're all due to the same cause.
Chet Ramey
2018-09-16 18:40:24 UTC
Permalink
Post by Eduardo Bustamante
(...)
Post by Chet Ramey
Thanks for the report. They are the same problem.
Thanks Chet. Do you have a patch for the issue? I have a few other
cases but I'm not sure if they're all due to the same cause.
Sure.
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU ***@case.edu http://tiswww.cwru.edu/~chet/
Eduardo A. Bustamante López
2018-09-16 08:12:28 UTC
Permalink
Here's another interesting crash:

$ base64 < 53
MBgFEBAQMBgFEBAfEA==

$ gdb -batch -ex=r -ex=bt --args ./bash --noprofile --norc -c 'PATH=; set -o emacs; IFS= read -re' < 53
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0
[Detaching after fork from child process 30991]
/home/dualbus/src/gnu/bash/bash: vim: No such file or directory
0
[Detaching after fork from child process 30992]
/home/dualbus/src/gnu/bash/bash: vim: No such file or directory

malloc: unknown:0: assertion botched
malloc: 0x630808: allocated: last allocated from unknown:0
free: called with already freed block argument
Aborting...
Program received signal SIGABRT, Aborted.
__GI_raise (sig=***@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
#0 __GI_raise (sig=***@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007ffff79a7535 in __GI_abort () at abort.c:79
#2 0x00000000004597bb in programming_error (format=0x5557be "free: called with already freed block argument") at error.c:175
#3 0x00000000005322c2 in xbotch (mem=0x630808, e=1, s=0x5557be "free: called with already freed block argument", file=0x0, line=0) at malloc.c:354
#4 0x000000000053155c in internal_free (mem=0x630808, file=0x0, line=0, flags=0) at malloc.c:931
#5 0x0000000000531d4f in free (mem=0x630808) at malloc.c:1388
#6 0x00000000004b5150 in xfree (string=0x630808) at xmalloc.c:150
#7 0x000000000051e94c in rl_do_undo () at undo.c:240
#8 0x000000000051eb23 in rl_revert_line (count=1, key=0) at undo.c:312
#9 0x00000000004fa7f9 in readline_internal_teardown (eof=1) at readline.c:471
#10 0x00000000004fa591 in readline_internal () at readline.c:672
#11 0x00000000004fa440 in readline (prompt=0x55466f "") at readline.c:377
#12 0x00000000004caa16 in edit_line (p=0x55466f "", itext=0x0) at ./read.def:1104
#13 0x00000000004c94ba in read_builtin (list=0x0) at ./read.def:563
#14 0x000000000044b599 in execute_builtin (builtin=0x4c8560 <read_builtin>, words=0x628f88, flags=0, subshell=0) at execute_cmd.c:4677
#15 0x000000000044a96f in execute_builtin_or_function (words=0x628f88, builtin=0x4c8560 <read_builtin>, var=0x0, redirects=0x0, fds_to_close=0x628ce8, flags=0) at execute_cmd.c:5185
#16 0x00000000004437c9 in execute_simple_command (simple_command=0x628c08, pipe_in=-1, pipe_out=-1, async=0, fds_to_close=0x628ce8) at execute_cmd.c:4449
#17 0x00000000004412ab in execute_command_internal (command=0x628bc8, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628ce8) at execute_cmd.c:840
#18 0x0000000000445208 in execute_connection (command=0x628d48, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628ce8) at execute_cmd.c:2689
#19 0x0000000000441681 in execute_command_internal (command=0x628d48, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628ce8) at execute_cmd.c:1013
#20 0x00000000004bf527 in parse_and_execute (string=0x628408 "PATH=; set -o emacs; IFS= read -re", from_file=0x5353fb "-c", flags=4) at evalstring.c:436
#21 0x0000000000423845 in run_one_command (command=0x7fffffffea92 "PATH=; set -o emacs; IFS= read -re") at shell.c:1416
#22 0x0000000000421920 in main (argc=5, argv=0x7fffffffe758, env=0x7fffffffe788) at shell.c:735


Bash compiled with:

`CC=clang CFLAGS='-O0 -ggdb' ./configure && make -j4' from `devel' (b52e30b8dd5bba5aed7b13040c9d4f7a0c1990cc) on Linux
(Ubuntu 18.04)
Chet Ramey
2018-09-16 18:39:07 UTC
Permalink
Post by Eduardo A. Bustamante López
$ base64 < 53
MBgFEBAQMBgFEBAfEA==
$ gdb -batch -ex=r -ex=bt --args ./bash --noprofile --norc -c 'PATH=; set -o emacs; IFS= read -re' < 53
I can't reproduce this on Mac OS X or Fedora 28.
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU ***@case.edu http://tiswww.cwru.edu/~chet/
Eduardo A. Bustamante López
2018-09-16 21:15:28 UTC
Permalink
Post by Chet Ramey
Post by Eduardo A. Bustamante López
$ base64 < 53
MBgFEBAQMBgFEBAfEA==
$ gdb -batch -ex=r -ex=bt --args ./bash --noprofile --norc -c 'PATH=; set -o emacs; IFS= read -re' < 53
I can't reproduce this on Mac OS X or Fedora 28.
Hm, I can reliably reproduce it with or without bash-malloc.

$ base64 -d <<< 'MBgFEBAQMBgFEBAfEA==' > 53

$ cat -v 53
0^X^E^P^P^P0^X^E^P^P^_^P

$ CC=clang CFLAGS='-O0 -ggdb' ./configure && make -j4
(...)

$ ./bash --noprofile --norc -c 'PATH=; set -o emacs; IFS= read -re < 53'
0
./bash: vim: No such file or directory
0rl_maybe_unsave_line: rl_undo_list=0x236c848
rl_maybe_unsave_line: rl_undo_list->next=(nil)
rl_maybe_unsave_line: rl_undo_list=0x236c848
rl_maybe_unsave_line: rl_undo_list->next=(nil)
0
./bash: vim: No such file or directory
rl_do_undo: rl_undo_list = (nil)
rl_do_undo: xfree(release = 0x236c848)
rl_maybe_unsave_line: rl_undo_list=0x2360188
rl_maybe_unsave_line: rl_undo_list->next=0x236c848
rl_do_undo: rl_undo_list = 0x236c848
rl_do_undo: xfree(release = 0x2360188)
rl_do_undo: rl_undo_list = 0x23601c0
rl_do_undo: xfree(release = 0x236c848)

malloc: unknown:0: assertion botched
malloc: 0x236c848: allocated: last allocated from unknown:0
free: called with already freed block argument
Aborting...Aborted


My interpretation of the issue is that the `^_' triggers an `undo', which then
causes bash to release that entry (i.e. `0x236c848' in the example above). Then
the `^P' somehow restores that free'd rl_undo_list entry and bash tries to free
it again during readline_internal_teardown.


Under GDB:

***@ubuntu:~/src/gnu/bash$ gdb --args ./bash --noprofile --norc -c 'PATH=; set -o emacs; IFS= read -re < 53'
GNU gdb (Ubuntu 8.2-0ubuntu1) 8.2
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./bash...done.
(gdb) b rl_maybe_unsave_line
Breakpoint 1 at 0x526128: file misc.c, line 354.
(gdb) b rl_do_undo
Breakpoint 2 at 0x51e6a8: file undo.c, line 175.
(gdb) r
Starting program: /home/dualbus/src/gnu/bash/bash --noprofile --norc -c PATH=\;\ set\ -o\ emacs\;\ IFS=\ read\ -re\ \<\ 53
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0
[Detaching after fork from child process 20660]
/home/dualbus/src/gnu/bash/bash: vim: No such file or directory
0
Breakpoint 1, rl_maybe_unsave_line () at misc.c:354
354 if (_rl_saved_line_for_history)
(gdb) bt
#0 rl_maybe_unsave_line () at misc.c:354
#1 0x00000000005266ea in rl_get_previous_history (count=1, key=16) at misc.c:618
#2 0x00000000004fb350 in _rl_dispatch_subseq (key=16, map=0x575db0 <emacs_standard_keymap>, got_subseq=0) at readline.c:852
#3 0x00000000004face9 in _rl_dispatch (key=16, map=0x575db0 <emacs_standard_keymap>) at readline.c:798
#4 0x00000000004fac59 in readline_internal_char () at readline.c:632
#5 0x00000000004fc282 in readline_internal_charloop () at readline.c:659
#6 0x00000000004fa5ae in readline_internal () at readline.c:671
#7 0x00000000004fa470 in readline (prompt=0x5546af "") at readline.c:377
#8 0x00000000004caa46 in edit_line (p=0x5546af "", itext=0x0) at ./read.def:1104
#9 0x00000000004c94ea in read_builtin (list=0x0) at ./read.def:563
#10 0x000000000044b599 in execute_builtin (builtin=0x4c8590 <read_builtin>, words=0x629428, flags=0, subshell=0) at execute_cmd.c:4677
#11 0x000000000044a96f in execute_builtin_or_function (words=0x629428, builtin=0x4c8590 <read_builtin>, var=0x0, redirects=0x628d08, fds_to_close=0x628dc8, flags=0) at execute_cmd.c:5185
#12 0x00000000004437c9 in execute_simple_command (simple_command=0x628c08, pipe_in=-1, pipe_out=-1, async=0, fds_to_close=0x628dc8) at execute_cmd.c:4449
#13 0x00000000004412ab in execute_command_internal (command=0x628bc8, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:840
#14 0x0000000000445208 in execute_connection (command=0x628d88, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:2689
#15 0x0000000000441681 in execute_command_internal (command=0x628d88, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:1013
#16 0x00000000004bf557 in parse_and_execute (string=0x628408 "PATH=; set -o emacs; IFS= read -re < 53", from_file=0x5353fb "-c", flags=4) at evalstring.c:436
#17 0x0000000000423845 in run_one_command (command=0x7fffffffea8d "PATH=; set -o emacs; IFS= read -re < 53") at shell.c:1416
#18 0x0000000000421920 in main (argc=5, argv=0x7fffffffe758, env=0x7fffffffe788) at shell.c:735
(gdb) c
Continuing.
rl_maybe_unsave_line: rl_undo_list=0x630868
rl_maybe_unsave_line: rl_undo_list->next=(nil)

Breakpoint 1, rl_maybe_unsave_line () at misc.c:354
354 if (_rl_saved_line_for_history)
(gdb) bt
#0 rl_maybe_unsave_line () at misc.c:354
#1 0x00000000005266ea in rl_get_previous_history (count=1, key=16) at misc.c:618
#2 0x00000000004fb350 in _rl_dispatch_subseq (key=16, map=0x575db0 <emacs_standard_keymap>, got_subseq=0) at readline.c:852
#3 0x00000000004face9 in _rl_dispatch (key=16, map=0x575db0 <emacs_standard_keymap>) at readline.c:798
#4 0x00000000004fac59 in readline_internal_char () at readline.c:632
#5 0x00000000004fc282 in readline_internal_charloop () at readline.c:659
#6 0x00000000004fa5ae in readline_internal () at readline.c:671
#7 0x00000000004fa470 in readline (prompt=0x5546af "") at readline.c:377
#8 0x00000000004caa46 in edit_line (p=0x5546af "", itext=0x0) at ./read.def:1104
#9 0x00000000004c94ea in read_builtin (list=0x0) at ./read.def:563
#10 0x000000000044b599 in execute_builtin (builtin=0x4c8590 <read_builtin>, words=0x629428, flags=0, subshell=0) at execute_cmd.c:4677
#11 0x000000000044a96f in execute_builtin_or_function (words=0x629428, builtin=0x4c8590 <read_builtin>, var=0x0, redirects=0x628d08, fds_to_close=0x628dc8, flags=0) at execute_cmd.c:5185
#12 0x00000000004437c9 in execute_simple_command (simple_command=0x628c08, pipe_in=-1, pipe_out=-1, async=0, fds_to_close=0x628dc8) at execute_cmd.c:4449
#13 0x00000000004412ab in execute_command_internal (command=0x628bc8, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:840
#14 0x0000000000445208 in execute_connection (command=0x628d88, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:2689
#15 0x0000000000441681 in execute_command_internal (command=0x628d88, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:1013
#16 0x00000000004bf557 in parse_and_execute (string=0x628408 "PATH=; set -o emacs; IFS= read -re < 53", from_file=0x5353fb "-c", flags=4) at evalstring.c:436
#17 0x0000000000423845 in run_one_command (command=0x7fffffffea8d "PATH=; set -o emacs; IFS= read -re < 53") at shell.c:1416
#18 0x0000000000421920 in main (argc=5, argv=0x7fffffffe758, env=0x7fffffffe788) at shell.c:735
(gdb) c
Continuing.
rl_maybe_unsave_line: rl_undo_list=0x630868
rl_maybe_unsave_line: rl_undo_list->next=(nil)
0
[Detaching after fork from child process 20661]
/home/dualbus/src/gnu/bash/bash: vim: No such file or directory

Breakpoint 2, rl_do_undo () at undo.c:175
175 start = end = waiting_for_begin = 0;
(gdb) bt
#0 rl_do_undo () at undo.c:175
#1 0x000000000051ec08 in rl_undo_command (count=1, key=31) at undo.c:333
#2 0x00000000004fb350 in _rl_dispatch_subseq (key=31, map=0x575db0 <emacs_standard_keymap>, got_subseq=0) at readline.c:852
#3 0x00000000004face9 in _rl_dispatch (key=31, map=0x575db0 <emacs_standard_keymap>) at readline.c:798
#4 0x00000000004fac59 in readline_internal_char () at readline.c:632
#5 0x00000000004fc282 in readline_internal_charloop () at readline.c:659
#6 0x00000000004fa5ae in readline_internal () at readline.c:671
#7 0x00000000004fa470 in readline (prompt=0x5546af "") at readline.c:377
#8 0x00000000004caa46 in edit_line (p=0x5546af "", itext=0x0) at ./read.def:1104
#9 0x00000000004c94ea in read_builtin (list=0x0) at ./read.def:563
#10 0x000000000044b599 in execute_builtin (builtin=0x4c8590 <read_builtin>, words=0x629428, flags=0, subshell=0) at execute_cmd.c:4677
#11 0x000000000044a96f in execute_builtin_or_function (words=0x629428, builtin=0x4c8590 <read_builtin>, var=0x0, redirects=0x628d08, fds_to_close=0x628dc8, flags=0) at execute_cmd.c:5185
#12 0x00000000004437c9 in execute_simple_command (simple_command=0x628c08, pipe_in=-1, pipe_out=-1, async=0, fds_to_close=0x628dc8) at execute_cmd.c:4449
#13 0x00000000004412ab in execute_command_internal (command=0x628bc8, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:840
#14 0x0000000000445208 in execute_connection (command=0x628d88, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:2689
#15 0x0000000000441681 in execute_command_internal (command=0x628d88, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:1013
#16 0x00000000004bf557 in parse_and_execute (string=0x628408 "PATH=; set -o emacs; IFS= read -re < 53", from_file=0x5353fb "-c", flags=4) at evalstring.c:436
#17 0x0000000000423845 in run_one_command (command=0x7fffffffea8d "PATH=; set -o emacs; IFS= read -re < 53") at shell.c:1416
#18 0x0000000000421920 in main (argc=5, argv=0x7fffffffe758, env=0x7fffffffe788) at shell.c:735
(gdb) c
Continuing.
rl_do_undo: rl_undo_list = (nil)
rl_do_undo: xfree(release = 0x630868)

Breakpoint 1, rl_maybe_unsave_line () at misc.c:354
354 if (_rl_saved_line_for_history)
(gdb) bt
#0 rl_maybe_unsave_line () at misc.c:354
#1 0x00000000005266ea in rl_get_previous_history (count=1, key=16) at misc.c:618
#2 0x00000000004fb350 in _rl_dispatch_subseq (key=16, map=0x575db0 <emacs_standard_keymap>, got_subseq=0) at readline.c:852
#3 0x00000000004face9 in _rl_dispatch (key=16, map=0x575db0 <emacs_standard_keymap>) at readline.c:798
#4 0x00000000004fac59 in readline_internal_char () at readline.c:632
#5 0x00000000004fc282 in readline_internal_charloop () at readline.c:659
#6 0x00000000004fa5ae in readline_internal () at readline.c:671
#7 0x00000000004fa470 in readline (prompt=0x5546af "") at readline.c:377
#8 0x00000000004caa46 in edit_line (p=0x5546af "", itext=0x0) at ./read.def:1104
#9 0x00000000004c94ea in read_builtin (list=0x0) at ./read.def:563
#10 0x000000000044b599 in execute_builtin (builtin=0x4c8590 <read_builtin>, words=0x629428, flags=0, subshell=0) at execute_cmd.c:4677
#11 0x000000000044a96f in execute_builtin_or_function (words=0x629428, builtin=0x4c8590 <read_builtin>, var=0x0, redirects=0x628d08, fds_to_close=0x628dc8, flags=0) at execute_cmd.c:5185
#12 0x00000000004437c9 in execute_simple_command (simple_command=0x628c08, pipe_in=-1, pipe_out=-1, async=0, fds_to_close=0x628dc8) at execute_cmd.c:4449
#13 0x00000000004412ab in execute_command_internal (command=0x628bc8, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:840
#14 0x0000000000445208 in execute_connection (command=0x628d88, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:2689
#15 0x0000000000441681 in execute_command_internal (command=0x628d88, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:1013
#16 0x00000000004bf557 in parse_and_execute (string=0x628408 "PATH=; set -o emacs; IFS= read -re < 53", from_file=0x5353fb "-c", flags=4) at evalstring.c:436
#17 0x0000000000423845 in run_one_command (command=0x7fffffffea8d "PATH=; set -o emacs; IFS= read -re < 53") at shell.c:1416
#18 0x0000000000421920 in main (argc=5, argv=0x7fffffffe758, env=0x7fffffffe788) at shell.c:735
(gdb) c
Continuing.
rl_maybe_unsave_line: rl_undo_list=0x6295c8
rl_maybe_unsave_line: rl_undo_list->next=0x630868

Breakpoint 2, rl_do_undo () at undo.c:175
175 start = end = waiting_for_begin = 0;
(gdb) bt
#0 rl_do_undo () at undo.c:175
#1 0x000000000051eb93 in rl_revert_line (count=1, key=0) at undo.c:314
#2 0x00000000004fa829 in readline_internal_teardown (eof=1) at readline.c:471
#3 0x00000000004fa5c1 in readline_internal () at readline.c:672
#4 0x00000000004fa470 in readline (prompt=0x5546af "") at readline.c:377
#5 0x00000000004caa46 in edit_line (p=0x5546af "", itext=0x0) at ./read.def:1104
#6 0x00000000004c94ea in read_builtin (list=0x0) at ./read.def:563
#7 0x000000000044b599 in execute_builtin (builtin=0x4c8590 <read_builtin>, words=0x629428, flags=0, subshell=0) at execute_cmd.c:4677
#8 0x000000000044a96f in execute_builtin_or_function (words=0x629428, builtin=0x4c8590 <read_builtin>, var=0x0, redirects=0x628d08, fds_to_close=0x628dc8, flags=0) at execute_cmd.c:5185
#9 0x00000000004437c9 in execute_simple_command (simple_command=0x628c08, pipe_in=-1, pipe_out=-1, async=0, fds_to_close=0x628dc8) at execute_cmd.c:4449
#10 0x00000000004412ab in execute_command_internal (command=0x628bc8, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:840
#11 0x0000000000445208 in execute_connection (command=0x628d88, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:2689
#12 0x0000000000441681 in execute_command_internal (command=0x628d88, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:1013
#13 0x00000000004bf557 in parse_and_execute (string=0x628408 "PATH=; set -o emacs; IFS= read -re < 53", from_file=0x5353fb "-c", flags=4) at evalstring.c:436
#14 0x0000000000423845 in run_one_command (command=0x7fffffffea8d "PATH=; set -o emacs; IFS= read -re < 53") at shell.c:1416
#15 0x0000000000421920 in main (argc=5, argv=0x7fffffffe758, env=0x7fffffffe788) at shell.c:735
(gdb) c
Continuing.
rl_do_undo: rl_undo_list = 0x630868
rl_do_undo: xfree(release = 0x6295c8)

Breakpoint 2, rl_do_undo () at undo.c:175
175 start = end = waiting_for_begin = 0;
(gdb) bt
#0 rl_do_undo () at undo.c:175
#1 0x000000000051eb93 in rl_revert_line (count=1, key=0) at undo.c:314
#2 0x00000000004fa829 in readline_internal_teardown (eof=1) at readline.c:471
#3 0x00000000004fa5c1 in readline_internal () at readline.c:672
#4 0x00000000004fa470 in readline (prompt=0x5546af "") at readline.c:377
#5 0x00000000004caa46 in edit_line (p=0x5546af "", itext=0x0) at ./read.def:1104
#6 0x00000000004c94ea in read_builtin (list=0x0) at ./read.def:563
#7 0x000000000044b599 in execute_builtin (builtin=0x4c8590 <read_builtin>, words=0x629428, flags=0, subshell=0) at execute_cmd.c:4677
#8 0x000000000044a96f in execute_builtin_or_function (words=0x629428, builtin=0x4c8590 <read_builtin>, var=0x0, redirects=0x628d08, fds_to_close=0x628dc8, flags=0) at execute_cmd.c:5185
#9 0x00000000004437c9 in execute_simple_command (simple_command=0x628c08, pipe_in=-1, pipe_out=-1, async=0, fds_to_close=0x628dc8) at execute_cmd.c:4449
#10 0x00000000004412ab in execute_command_internal (command=0x628bc8, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:840
#11 0x0000000000445208 in execute_connection (command=0x628d88, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:2689
#12 0x0000000000441681 in execute_command_internal (command=0x628d88, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x628dc8) at execute_cmd.c:1013
#13 0x00000000004bf557 in parse_and_execute (string=0x628408 "PATH=; set -o emacs; IFS= read -re < 53", from_file=0x5353fb "-c", flags=4) at evalstring.c:436
#14 0x0000000000423845 in run_one_command (command=0x7fffffffea8d "PATH=; set -o emacs; IFS= read -re < 53") at shell.c:1416
#15 0x0000000000421920 in main (argc=5, argv=0x7fffffffe758, env=0x7fffffffe788) at shell.c:735
(gdb) c
Continuing.
rl_do_undo: rl_undo_list = 0x629600
rl_do_undo: xfree(release = 0x630868)

malloc: unknown:0: assertion botched
malloc: 0x630868: allocated: last allocated from unknown:0
free: called with already freed block argument
Aborting...
Program received signal SIGABRT, Aborted.
__GI_raise (sig=***@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.


$ git diff
diff --git a/builtins/read.def b/builtins/read.def
index a73905c3..0451266f 100644
--- a/builtins/read.def
+++ b/builtins/read.def
@@ -390,7 +390,7 @@ read_builtin (list)
sync_buffered_stream (default_buffered_input);
#endif

-#if 1
+#if 0
input_is_tty = isatty (fd);
#else
input_is_tty = 1;
diff --git a/lib/readline/misc.c b/lib/readline/misc.c
index 64b1457d..38e1d40e 100644
--- a/lib/readline/misc.c
+++ b/lib/readline/misc.c
@@ -357,6 +357,10 @@ rl_maybe_unsave_line (void)
list from a history entry, as in rl_replace_from_history() below. */
rl_replace_line (_rl_saved_line_for_history->line, 0);
rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
+ fprintf(stderr, "rl_maybe_unsave_line: rl_undo_list=%p\n", rl_undo_list);
+ if(rl_undo_list) {
+ fprintf(stderr, "rl_maybe_unsave_line: rl_undo_list->next=%p\n", rl_undo_list->next);
+ }
_rl_free_history_entry (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
rl_point = rl_end; /* rl_replace_line sets rl_end */
diff --git a/lib/readline/undo.c b/lib/readline/undo.c
index 75874e5d..4c06483e 100644
--- a/lib/readline/undo.c
+++ b/lib/readline/undo.c
@@ -237,6 +237,8 @@ rl_do_undo (void)

_hs_replace_history_data (-1, (histdata_t *)release, (histdata_t *)rl_undo_list);

+ fprintf(stderr, "rl_do_undo: rl_undo_list = %p\n", rl_undo_list);
+ fprintf(stderr, "rl_do_undo: xfree(release = %p)\n", release);
xfree (release);
}
while (waiting_for_begin);
Chet Ramey
2018-09-16 23:24:13 UTC
Permalink
Post by Chet Ramey
Post by Eduardo A. Bustamante López
$ base64 < 53
MBgFEBAQMBgFEBAfEA==
$ gdb -batch -ex=r -ex=bt --args ./bash --noprofile --norc -c 'PATH=; set -o emacs; IFS= read -re' < 53
I can't reproduce this on Mac OS X or Fedora 28.
OK, let me look around some more with your debugging hints. If I find it,
it will be in the next devel branch push.
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU ***@case.edu http://tiswww.cwru.edu/~chet/
Eduardo A. Bustamante López
2018-09-18 03:41:59 UTC
Permalink
Post by Chet Ramey
Post by Chet Ramey
Post by Eduardo A. Bustamante López
$ base64 < 53
MBgFEBAQMBgFEBAfEA==
$ gdb -batch -ex=r -ex=bt --args ./bash --noprofile --norc -c 'PATH=; set -o emacs; IFS= read -re' < 53
I can't reproduce this on Mac OS X or Fedora 28.
OK, let me look around some more with your debugging hints. If I find it,
it will be in the next devel branch push.
Hah! Thanks for the fix to rl_do_undo. I appreciate the comments, it makes it
easier to understand what's going on.

I ran this latest push through the set of crashes I found. They're all fixed.

Thanks again!

Loading...