Re: Documentation issue

2017-10-27 Thread Eli Barzilay
On Fri, Oct 27, 2017 at 2:37 AM, Clark Wang  wrote:
>
> What `unset' does is special but there's nothing special when parsing
> the command and bash even does not care if it's built-in command or
> not.

Exactly -- and this kind of a clarification is exactly the thing that
many people are unaware of.

(And in case it wasn't clear: I said that unset is different in the
expectations that people have with it, not in how it expands.)

-- 
   ((x=>x(x))(x=>x(x)))  Eli Barzilay:
   http://barzilay.org/  Maze is Life!



Out-of-bounds read in parse_comsub()

2017-10-27 Thread Jakub Wilk

Machine: i686
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -Og -fsanitize=address -Wno-parentheses 
-Wno-format-security
uname output: Linux debian 4.9.0-4-686-pae #1 SMP Debian 4.9.51-1 (2017-09-28) 
i686 GNU/Linux
Machine Type: i686-pc-linux-gnu

Bash Version: 20171020 snapshot

Apparently an out-of-bounds read can happen in parse_comsub() when 
checking script sytnax. To reproduce, rebuild bash with AddressSanitizer 
enabled and run:


  $ printf 
'$(00\177%012d\1%d00\177%090d\177%028d(%0267d\177%010d<<-\276%019d\n\n' | bash 
-n
  =
  ==15619==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb3b03a00 
at pc 0xb722991e bp 0xbff6d7b8 sp 0xbff6d390
  READ of size 2 at 0xb3b03a00 thread T0
  #0 0xb722991d  (/usr/lib/i386-linux-gnu/libasan.so.4+0x5491d)
  #1 0x4e92d9 in parse_comsub parse.y:3841
  #2 0x4ee81a in read_token_word parse.y:4969
  #3 0x4f0d2a in read_token parse.y:3350
  #4 0x4f137e in yylex parse.y:2691
  #5 0x4f21af in yyparse y.tab.c:1821
  #6 0x4e05e9 in parse_command eval.c:294
  #7 0x4e080d in read_command eval.c:338
  #8 0x4e12d2 in reader_loop eval.c:140
  #9 0x4e0357 in main shell.c:804
  #10 0xb700d285 in __libc_start_main 
(/lib/i386-linux-gnu/libc.so.6+0x18285)
  #11 0x4db500  (.../bash+0x3e500)

  0xb3b03a00 is located 0 bytes to the right of 448-byte region 
[0xb3b03840,0xb3b03a00)
  allocated by thread T0 here:
  #0 0xb72b41d4 in __interceptor_realloc 
(/usr/lib/i386-linux-gnu/libasan.so.4+0xdf1d4)
  #1 0x5c35d0 in xrealloc xmalloc.c:133

  ...

Found using American Fuzzy Lop:
http://lcamtuf.coredump.cx/afl/

--
Jakub Wilk



'fc' outputing text of DEBUG trap

2017-10-27 Thread Boruch Baum
In Debian, using Bash version 4.4, path level 12, I've set a DEBUG trap
in my .bashrc and tried running the following command, with the
following output resulting. The five lines between the command being run
by fc and that command's output, is the text of the DEBUG trap.


1075 $ fc -e true 1072 1073
which mutt
 >/dev/tty \
   printf "\033%s${title_fmt}" "[01;00m" "${BASH_COMMAND}"; \
   [[ -z ${prior_cmd}  ]] && SECONDS=0 ;\
   [[ "${BASH_COMMAND}" != "my_prompt_command" ]]   \
   && { prior_cmd="${BASH_COMMAND}"; SECONDS=0; }   \

/usr/bin/mutt
which bash
 >/dev/tty \
   printf "\033%s${title_fmt}" "[01;00m" "${BASH_COMMAND}"; \
   [[ -z ${prior_cmd}  ]] && SECONDS=0 ;\
   [[ "${BASH_COMMAND}" != "my_prompt_command" ]]   \
   && { prior_cmd="${BASH_COMMAND}"; SECONDS=0; }   \

/bin/bash

-- 
hkp://keys.gnupg.net
CA45 09B5 5351 7C11 A9D1  7286 0036 9E45 1595 8BC0



Re: 'fc' outputing text of DEBUG trap

2017-10-27 Thread Eduardo Bustamante
On Fri, Oct 27, 2017 at 1:21 AM, Boruch Baum  wrote:
> In Debian, using Bash version 4.4, path level 12, I've set a DEBUG trap
> in my .bashrc and tried running the following command, with the
> following output resulting. The five lines between the command being run
> by fc and that command's output, is the text of the DEBUG trap.

Here's a short reproducer:

dualbus@ubuntu:~$ HISTFILE=/dev/null bash --norc --noprofile -O extdebug
bash-4.4$ trap ': it is a trap' DEBUG
bash-4.4$ echo hi
hi
bash-4.4$ history
1  trap ': it is a trap' DEBUG
2  echo hi
3  history
bash-4.4$ fc -e true 1 3
trap ': it is a trap' DEBUG
: it is a trap
echo hi
: it is a trap
hi
history
: it is a trap
1  trap ': it is a trap' DEBUG
2  echo hi
3  history
4  trap ': it is a trap' DEBUG
5  echo hi
6  history
bash-4.4$
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)



Re: Out-of-bounds read in parse_comsub()

2017-10-27 Thread Eduardo A . Bustamante López
On Thu, Oct 26, 2017 at 11:07:57PM +0200, Jakub Wilk wrote:
[...]
> Bash Version: 20171020 snapshot
> 
> Apparently an out-of-bounds read can happen in parse_comsub() when checking
> script sytnax. To reproduce, rebuild bash with AddressSanitizer enabled and
> run:
> 
>   $ printf 
> '$(00\177%012d\1%d00\177%090d\177%028d(%0267d\177%010d<<-\276%019d\n\n' | 
> bash -n

I can reproduce this error too. It seems `ret' is missing a NUL terminator, so
`STREQN' reads past the allocated buffer.


I'm not sure if this is the right fix, but at least it makes the issue go away 
for me:


dualbus@ubuntu:~/src/gnu/build-bash-devel$ CFLAGS='-g -O0 -fsanitize=address' 
../bash/configure --without-bash-malloc && make -j8
[...]
dualbus@ubuntu:~/src/gnu/build-bash-devel$ printf 
'$(00\177%012d\1%d00\177%090d\177%028d(%0267d\177%010d<<-\276%019d\n\n' | 
./bash -n
./bash: line 1: unexpected EOF while looking for matching `)'
./bash: line 3: syntax error: unexpected end of file


diff --git a/parse.y b/parse.y
index 623648c6..67d9b3c3 100644
--- a/parse.y
+++ b/parse.y
@@ -3838,6 +3838,7 @@ eof_error:
  tind = lex_firstind;
  while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
tind++;
+ ret[retsize - 1] = '\0';
  if (STREQN (ret + tind, heredelim, hdlen))
{
  tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC|LEX_QUOTEDDOC);



Re: Documentation issue

2017-10-27 Thread Chet Ramey
On 10/26/17 10:50 PM, Clark Wang wrote:
> On Fri, Oct 27, 2017 at 3:00 AM, Eli Barzilay  wrote:
> 
>> On Thu, Oct 26, 2017 at 2:02 PM, Chet Ramey  wrote:
>>>
>>> It's more of a general statement about arrays, though it appears in
>>> the paragraph that discusses unset, so it's in the man page section on
>>> arrays.  You have to be careful about putting the same information in
>>> too many different places -- the man page is big enough already.
>>
>> I'm very aware of man page bloat and the fact that the bash page is very
>> long as is.  But (a) I think that the builtin section for each command
>> is the more important place for such things; and (b) what I'm suggesting
>> is just a short reminder sentence about the need for quoting unsets for
>> array elements.
>>
>> To make it more concrete, I think that the following change will be
>> good:
>>
>> 1. Drop the current "Care must be taken ... the entire array." two
>>sentences and replace them with some "See the unset builtin
>>description below".
>>
> 
> It's not only about unset. You also need to take care of other builtin
> commands:

Let's see if I can find some compromise language that will take care
of the general case. Since it's a compromise, no one will be satisfied,
of course.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: Out-of-bounds read in parse_comsub()

2017-10-27 Thread Chet Ramey
On 10/27/17 11:32 AM, Eduardo A. Bustamante López wrote:
> On Thu, Oct 26, 2017 at 11:07:57PM +0200, Jakub Wilk wrote:
> [...]
>> Bash Version: 20171020 snapshot
>>
>> Apparently an out-of-bounds read can happen in parse_comsub() when checking
>> script sytnax. To reproduce, rebuild bash with AddressSanitizer enabled and
>> run:
>>
>>   $ printf 
>> '$(00\177%012d\1%d00\177%090d\177%028d(%0267d\177%010d<<-\276%019d\n\n' | 
>> bash -n
> 
> I can reproduce this error too. It seems `ret' is missing a NUL terminator, so
> `STREQN' reads past the allocated buffer.

Thanks for the report and the pointer to the right place to fix.  Here's
the fix I went with.

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
*** ../bash-20171020/parse.y2017-10-01 20:25:17.0 -0400
--- parse.y 2017-10-27 15:08:29.0 -0400
***
*** 3839,3843 
  while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
tind++;
! if (STREQN (ret + tind, heredelim, hdlen))
{
  tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC|LEX_QUOTEDDOC);
--- 3839,3843 
  while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
tind++;
! if (retind-tind == hdlen && STREQN (ret + tind, heredelim, hdlen))
{
  tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC|LEX_QUOTEDDOC);