bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: parsing command substitution inside parameter expansion in interacti


From: Grisha Levit
Subject: Re: parsing command substitution inside parameter expansion in interactive shell
Date: Sun, 26 Mar 2023 01:26:39 -0400

On Mon, Mar 20, 2023 at 4:59 PM Chet Ramey <chet.ramey@case.edu> wrote:
> Thanks, it's an easy fix to preserve the newline here.

FWIW even with the latest fixes, this kind of nesting in a history
entry still triggers ASAN:

bash --norc -in <<<$'${_+$(\n \cP\en '

ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 1 at 0x000105c0c2cf thread T0
    #0 bash_add_history bashhist.c:898
    #1 maybe_add_history bashhist.c:759
    #2 pre_process_line bashhist.c:628
    #3 shell_getc parse.y:2501
    #4 read_token parse.y:3425
    #5 yylex parse.y:2915
    #6 yyparse y.tab.c:1869
    #7 parse_comsub parse.y:4306
    #8 parse_matched_pair parse.y:3973
    #9 read_token_word parse.y:5172
    #10 read_token parse.y:3621
    #11 yylex parse.y:2915
    #12 yyparse y.tab.c:1869
    #13 parse_command eval.c:345
    #14 read_command eval.c:389
    #15 reader_loop eval.c:139
    #16 main shell.c:821

Avoided by:

diff --git a/bashhist.c b/bashhist.c
index 21c77058..b48306c2 100644
--- a/bashhist.c
+++ b/bashhist.c
@@ -895,7 +895,7 @@ bash_add_history (char *line)
             newline, since that is what happens when the line is parsed. */
          curlen = strlen (current->line);

-         if (dstack.delimiter_depth == 0 && current->line[curlen - 1]
== '\\' &&
+         if (curlen && dstack.delimiter_depth == 0 &&
current->line[curlen - 1] == '\\' &&
              (curlen < 2 || current->line[curlen - 2] != '\\'))
            {
              current->line[curlen - 1] = '\0';

----

bash --norc -in <<<$'${_+$(\n\e.'

ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 1 at 0x00010870c517 thread T0
    #0 history_tokenize_word histexpand.c:1561
    #1 history_tokenize_internal histexpand.c:1660
    #2 history_tokenize histexpand.c:1693
    #3 history_arg_extract histexpand.c:1435
    #4 rl_yank_nth_arg_internal kill.c:628
    #5 rl_yank_last_arg kill.c:698
    #6 _rl_dispatch_subseq readline.c:922

Avoided by:

diff --git a/lib/readline/histexpand.c b/lib/readline/histexpand.c
index d21240bf..8a147e40 100644
--- a/lib/readline/histexpand.c
+++ b/lib/readline/histexpand.c
@@ -1603,6 +1603,8 @@ get_word:
          delimopen = '(';
          delimiter = ')';
          nestdelim = 1;
+          if (string[i] == 0)
+            break;
          continue;
        }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]