zsh-workers
 help / color / mirror / code / Atom feed
* Zsh parser infinite loop in chuck from utils.c on malformed input
@ 2017-05-08 14:00 Eduardo Bustamante
  2017-05-08 14:17 ` Eduardo Bustamante
  2017-05-10  6:43 ` Bart Schaefer
  0 siblings, 2 replies; 6+ messages in thread
From: Eduardo Bustamante @ 2017-05-08 14:00 UTC (permalink / raw)
  To: zsh-workers; +Cc: Eduardo A. Bustamante López

I'm not sure if this is working as expected, but the following input
causes Zsh running with noexec to loop forever.

dualbus@debian:~/bash-fuzzing/zsh-parser$ cat -v loop
${(%%%%EuzktiOn)aY-^@|M-z^?^@M-^@M-^@M-^?M-^?M-^?ct/^\%{2///^\%ll^@^@M-u./L/+/M-^?M-^?M-^?^?//o//,{}}M-^?M-^?M-^?M-^@^@^A/////^\%333333333333333333333333333{(ifll^@^@^A//L/+///^A///^^//,{}}M-^?M-^?^@}/PJ;//5///^B"_
@#M-^?M-^?M-^?K&^@^B^@^@        M-h3#^B#M-^?M-^?M-^?^?$)0#^@^BM-b^@>&,"^@
M-^?^?
@M-^?M-^?M-^?K&^D^B^@G]@ M-bM-m=&,"^@
,"^@inM-^?
@M-^?M-^?
^M^?55`55^G!;M-3

dualbus@debian:~/bash-fuzzing/zsh-parser$ base64 loop
JHsoJSUlJUV1emt0aU9uKWFZLQB8+n8AgID///9jdC8cJXsyLy8vHCVsbAAA9S4vTC8rL////38v
L28vLyx7fX3///+AAAEvLy8vLxwlMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzeyhpZmxsAAAB
Ly9MLysvLy8BLy8vHi8vLHt9ff//AH0vUEo7Ly81Ly8vAiJfCkAj////SyYAAgAACegzIwIj////
fyQpMCMAAuIAPiYsIgAK/38KQP///0smBAIAR11AIOLtPSYsIgAKLCIAaW7/CkD//woNfzU1YDU1
ByE7swo=

(gdb) r -n loop
Starting program: /home/dualbus/src/zsh/zsh/Src/zsh -n loop
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
loop:1: number truncated after 20 digits:
333333333333333333333333333(ifll^@^@^A//L/+///^A///^^//\M-^?\M-^?^@
loop:1: number truncated after 20 digits:
333333333333333333333333333{}\M-^?\M-^?^@
^C
Program received signal SIGINT, Interrupt.
0x00000000004cab23 in chuck (str=0x7fffc89f774f '\241' <repeats 200
times>...) at utils.c:2229
2229        while ((str[0] = str[1]))
(gdb) bt
#0  0x00000000004cab23 in chuck (str=0x7fffc89f774f '\241' <repeats
200 times>...) at utils.c:2229
#1  0x00000000004aa16c in promptexpand (
    s=0x7ffff7e5b938 "\203 |\372\177\203
\200\200\377\377\377ct/\034%2///\034%ll\203 \203
\365./L/+/\377\377\377\177//o//\377\377\377\200\203 \001/////\034%",
'3' <repeats 27 times>, "{}\377\377\203 ", ns=0, rs=0x0, Rs=0x0,
txtchangep=0x0) at prompt.c:227
#2  0x00000000004bd636 in paramsubst (l=0x7fffffffbf90,
n=0x7ffff7e5b6f8, str=0x7fffffffb940, qt=0, pf_flags=0,
    ret_flags=0x7fffffffbf1c) at subst.c:3580
#3  0x00000000004b4f33 in stringsubst (list=0x7fffffffbf90,
node=0x7ffff7e5b6f8, pf_flags=0, ret_flags=0x7fffffffbf1c, asssub=0)
    at subst.c:247
#4  0x00000000004b42e5 in prefork (list=0x7fffffffbf90, flags=0,
ret_flags=0x7fffffffbf1c) at subst.c:85
#5  0x0000000000440df5 in execcmd_getargs (preargs=0x7ffff7e5b6e0,
args=0x7ffff7e5b618, expand=1) at exec.c:2659
#6  0x000000000043c1eb in execcmd_exec (state=0x7fffffffde30,
eparams=0x7fffffffccf0, input=0, output=0, how=2, last1=2)
    at exec.c:2765
#7  0x000000000043b804 in execpline2 (state=0x7fffffffde30, pcode=131,
how=2, input=0, output=0, last1=0) at exec.c:1873
#8  0x0000000000433f6e in execpline (state=0x7fffffffde30,
slcode=3074, how=2, last1=0) at exec.c:1602
#9  0x0000000000432dfe in execlist (state=0x7fffffffde30,
dont_change_job=0, exiting=0) at exec.c:1360
#10 0x000000000043277e in execode (p=0x7ffff7e5b4e8,
dont_change_job=0, exiting=0, context=0x4d90c4 "toplevel") at
exec.c:1141
#11 0x000000000045e366 in loop (toplevel=1, justonce=0) at init.c:208
#12 0x00000000004627d6 in zsh_main (argc=3, argv=0x7fffffffe458) at init.c:1692
#13 0x0000000000411a32 in main (argc=3, argv=0x7fffffffe458) at ./main.c:93
(gdb) p str
$1 = 0x7fffc89f774f '\241' <repeats 200 times>...


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Zsh parser infinite loop in chuck from utils.c on malformed input
  2017-05-08 14:00 Zsh parser infinite loop in chuck from utils.c on malformed input Eduardo Bustamante
@ 2017-05-08 14:17 ` Eduardo Bustamante
  2017-05-10  6:43 ` Bart Schaefer
  1 sibling, 0 replies; 6+ messages in thread
From: Eduardo Bustamante @ 2017-05-08 14:17 UTC (permalink / raw)
  To: zsh-workers; +Cc: Eduardo A. Bustamante López

[-- Attachment #1: Type: text/plain, Size: 322 bytes --]

On Mon, May 8, 2017 at 9:00 AM, Eduardo Bustamante <dualbus@gmail.com> wrote:
> I'm not sure if this is working as expected, but the following input
> causes Zsh running with noexec to loop forever.
[...]

dualbus@debian:~/bash-fuzzing/zsh-parser$ md5sum loop
a94ab3aa549b01a089d091f146dc3bcc  loop

File `loop' attached.

[-- Attachment #2: loop --]
[-- Type: application/octet-stream, Size: 233 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Zsh parser infinite loop in chuck from utils.c on malformed input
  2017-05-08 14:00 Zsh parser infinite loop in chuck from utils.c on malformed input Eduardo Bustamante
  2017-05-08 14:17 ` Eduardo Bustamante
@ 2017-05-10  6:43 ` Bart Schaefer
  2017-05-10 14:20   ` Eduardo Bustamante
  1 sibling, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 2017-05-10  6:43 UTC (permalink / raw)
  To: zsh-workers, zsh-workers

On May 8,  9:00am, Eduardo Bustamante wrote:
}
} I'm not sure if this is working as expected, but the following input
} causes Zsh running with noexec to loop forever.

The basis of this is ${(%%%%EuzktiOn)aY- which is the expansion of $aY
with a whole lot of parameter flags.  Since aY is unset, the last "-"
means that most of the flags are instead applied to all the rest of
the crap that follows.

This probably should have been a parse error because the { } are not
balanced, but I'm guessing the parser returns a complete expression
when it hits EOF.  Anyway, parameter expansion is one of the few things
that happens in noexec, and those %%%% in the flags list mean to treat
all that garbage as a prompt ... so I suspect it's not actually in an
*infinite* loop, just one that is going to repeat 3333333333333333333
times.

Unless we want to put some arbitrary limits on numbers used in prompt
expansion, I don't think there's anything to be done here.  Even if
the unbalanced { } were detected, adding another } at the end of the
file would probably bring back the looping.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Zsh parser infinite loop in chuck from utils.c on malformed input
  2017-05-10  6:43 ` Bart Schaefer
@ 2017-05-10 14:20   ` Eduardo Bustamante
  2017-05-10 14:45     ` Peter Stephenson
  0 siblings, 1 reply; 6+ messages in thread
From: Eduardo Bustamante @ 2017-05-10 14:20 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-workers

On Wed, May 10, 2017 at 1:43 AM, Bart Schaefer
<schaefer@brasslantern.com> wrote:
[...]
> This probably should have been a parse error because the { } are not
> balanced, but I'm guessing the parser returns a complete expression
> when it hits EOF.  Anyway, parameter expansion is one of the few things
> that happens in noexec, and those %%%% in the flags list mean to treat
> all that garbage as a prompt ... so I suspect it's not actually in an
> *infinite* loop, just one that is going to repeat 3333333333333333333
> times.

I see. Is there a particular reason parameter expansion is performed
when noexec is on, and is there a way to disable expansions too?

(I'm interested in finding parsing problems, so this specific case
will most likely slow down the fuzzing).


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Zsh parser infinite loop in chuck from utils.c on malformed input
  2017-05-10 14:20   ` Eduardo Bustamante
@ 2017-05-10 14:45     ` Peter Stephenson
  2017-05-10 14:57       ` Eduardo Bustamante
  0 siblings, 1 reply; 6+ messages in thread
From: Peter Stephenson @ 2017-05-10 14:45 UTC (permalink / raw)
  To: Eduardo Bustamante, zsh-workers; +Cc: Eduardo Bustamante

On Wed, 10 May 2017 09:20:47 -0500
Eduardo Bustamante <dualbus@gmail.com> wrote:
> On Wed, May 10, 2017 at 1:43 AM, Bart Schaefer
> <schaefer@brasslantern.com> wrote:
> [...]
> > This probably should have been a parse error because the { } are not
> > balanced, but I'm guessing the parser returns a complete expression
> > when it hits EOF.  Anyway, parameter expansion is one of the few things
> > that happens in noexec, and those %%%% in the flags list mean to treat
> > all that garbage as a prompt ... so I suspect it's not actually in an
> > *infinite* loop, just one that is going to repeat 3333333333333333333
> > times.
> 
> I see. Is there a particular reason parameter expansion is performed
> when noexec is on, and is there a way to disable expansions too?

The problem is NO_EXEC is all things to all people; in the case of a
shell there isn't really "just" a syntax check, because it's too
flexible.  The result of a parameter expansion can in some cases have
a significant effect on what you're doing, in particular if the command
to execute is part of it.  Being able to parse a parameter substitution
is itself quite an important check; and there's no fundamental
difference in the code between looking through the parameter
substitution and changing the arguments based on what you find.  The
name NO_EXEC, rather than, say, SYNTAX_CHECK, is significant.

Adding an additional mode that does even less is certainly possible, but
not necessarily of very wide applicability.

pws


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Zsh parser infinite loop in chuck from utils.c on malformed input
  2017-05-10 14:45     ` Peter Stephenson
@ 2017-05-10 14:57       ` Eduardo Bustamante
  0 siblings, 0 replies; 6+ messages in thread
From: Eduardo Bustamante @ 2017-05-10 14:57 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: zsh-workers

On Wed, May 10, 2017 at 9:45 AM, Peter Stephenson
<p.stephenson@samsung.com> wrote:
[...]
> The problem is NO_EXEC is all things to all people; in the case of a
> shell there isn't really "just" a syntax check, because it's too
> flexible.  The result of a parameter expansion can in some cases have
> a significant effect on what you're doing, in particular if the command
> to execute is part of it.  Being able to parse a parameter substitution
> is itself quite an important check; and there's no fundamental
> difference in the code between looking through the parameter
> substitution and changing the arguments based on what you find.  The
> name NO_EXEC, rather than, say, SYNTAX_CHECK, is significant.
>
> Adding an additional mode that does even less is certainly possible, but
> not necessarily of very wide applicability.

Oh, I agree. Take for example:

  dualbus@debian:~$ for sh in bash ksh93 mksh dash zsh; do echo $sh
$($sh -n <<< 'echo x; ${a$b}' 2>&1); done
  bash
  ksh93 ksh93: syntax error at line 1: `$' unexpected
  mksh
  dash
  zsh zsh: bad substitution

Only ksh93 and zsh are able to detect the problematic parameter
expansion under noexec.

And I don't think there's enough value in implementing an additional
mode. I can just hack the source to disable the bits that I find
problematic for fuzzing.

Thank you for your answers!


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-05-10 14:57 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-08 14:00 Zsh parser infinite loop in chuck from utils.c on malformed input Eduardo Bustamante
2017-05-08 14:17 ` Eduardo Bustamante
2017-05-10  6:43 ` Bart Schaefer
2017-05-10 14:20   ` Eduardo Bustamante
2017-05-10 14:45     ` Peter Stephenson
2017-05-10 14:57       ` Eduardo Bustamante

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).