Commit Graph

1776 Commits

Author SHA1 Message Date
Denys Vlasenko
a2633aa819 hush: add func6.tests
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 20:12:10 +02:00
Denys Vlasenko
35ec818fa2 ash: fix "return N" not setting $? in loop conditionals
Upstream commit 1:

    Date: Mon, 6 Oct 2014 20:45:04 +0800
    [EVAL] Move common skipcount logic into skiploop

    The functions evalloop and evalfor share the logic on checking
    and updating skipcount.  This patch moves that into the helper
    function skiploop.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Upstream commit 2:

    Date: Mon, 6 Oct 2014 21:22:43 +0800
    [BUILTIN] Allow return in loop conditional to set exit status

    https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=332954

    When return is used in a loop conditional the exit status will
    be lost because we always set the exit status at the end of the
    loop to that of the last command executed in the body.

    This is counterintuitive and contrary to what most other shells do.

    This patch fixes this by always preserving the exit status of
    return when it is used in a loop conditional.

    The patch was originally written by Gerrit Pape <pape@smarden.org>.

    Reported-by: Stephane Chazelas <stephane_chazelas@yahoo.fr>
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 19:56:52 +02:00
Denys Vlasenko
1b8e0e8adf ash testsuite: remove two more inadvertent bashisms
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 17:43:04 +02:00
Denys Vlasenko
cc0056db5c ash testsuite: remove two inadvertent bashisms
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 17:30:21 +02:00
Denys Vlasenko
4d12e944ea ash: [ERROR] Set exitstatus in onint
Partially backported this commit:

    Date: Thu, 2 Oct 2014 21:07:55 +0800
    [ERROR] Set exitstatus in onint

    Currently the exit status when we receive SIGINT is set in evalcommand
    which means that it doesn't always get set.  For example, if you press
    CTRL-C at the prompt of an interactive dash, the exit status is not
    set to 130 as it is in many other Bourne shells.

    This patch fixes this by moving the setting of the exit status into
    onint which also simplifies evalcommand.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

The part after "if (evalbltin(cmdentry.u.cmd, argc, argv, flags))"
causes testsuite failures in signal handling, so left unchanged.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 16:03:11 +02:00
Denys Vlasenko
0840c91909 ash: [EVAL] Revert SKIPEVAL into EXEXIT
Upstream commit:

    Date:   Tue Aug 11 20:56:53 2009 +1000
    [EVAL] Revert SKIPEVAL into EXEXIT

    Now that eval handles EV_TESTED correctly, we can remove the
    SKIPEVAL hack and simply use EXEXIT for set -e.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 15:27:44 +02:00
Denys Vlasenko
7b3fa1e441 ash: [EVAL] Pass EV_TESTED into evalcmd
Upstream commit:

    Date:   Tue Aug 11 20:48:15 2009 +1000
    [EVAL] Pass EV_TESTED into evalcmd

    This patch fixes the case where the eval command is used with
    set -e and as part of a construct that should not cause the
    shell to abort, e.g., as part of the condition of an if statement.

    This is achieved by propagating the EV_TESTED flag into the
    evalstring function through evalcmd.  As this alters the prototype
    of evalcmd it is now invoked explicitly by evalbltin.  The built-in
    infrastructure has been changed to accomodate this special case.

    In order to ensure that the EXIT trap is properly executed this
    patch clears evalskip in exitshell.  This wasn't needed before
    because of the broken way evalstring worked where it always clears
    evalskip when called by minusc.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Although, I failed to create a reproducer for this.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 15:10:16 +02:00
Denys Vlasenko
08089c7c85 ash: fix a thinko in the last commit
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 14:47:52 +02:00
Denys Vlasenko
514b51ddf3 ash: make internal globbing code selectable from config
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 14:33:08 +02:00
Denys Vlasenko
cac4d002e7 ash: explain how "command" is handled, and shrink it a bit
function                                             old     new   delta
getoptscmd                                           641     632      -9
commandcmd                                            79      69     -10
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-19)             Total: -19 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-10-01 03:02:25 +02:00
Denys Vlasenko
e627ac95be ash: [VAR] Initialise OPTIND after importing environment
Upstream commit 1:

    Date: Fri, 23 Aug 2013 21:27:42 +1000
    [VAR] Initialise OPTIND after importing environment

    On Sat, Mar 23, 2013 at 01:46:20AM +0000, Chris F.A. Johnson wrote:
    >   According to both the dash man page and the POSIX spec, "When the
    >   shell is invoked, OPTIND is initialized to 1."
    >
    >   However, it actually takes the value of the environment variable
    >   if it exists:
    >
    > $ OPTIND=4 dash -c 'echo "$OPTIND"'
    > 4
    > $ OPTIND=4 bash -c 'echo "$OPTIND"'
    > 1
    > $ OPTIND=4 ksh -c 'echo "$OPTIND"'
    > 1
    > $ OPTIND=4 ksh93 -c 'echo "$OPTIND"'
    > 1

    This patch fixes this by initialising OPTIND after importing the
    environment.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Upstream commit 2:

    Date: Tue, 7 Oct 2014 22:24:42 +0800
    [VAR] Use setvareq to set OPTIND initially

    There is no need to setvarint to set the initial value of OPTIND
    of one.  This patch switchs to setvareq which also lets us avoid
    an unnecessary memory allocation.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-30 14:46:41 +02:00
Denys Vlasenko
6a0710e954 ash: [BUILTIN] Merge SKIPFUNC/SKIPFILE and only clear SKIPFUNC when leaving dotcmd
Upstream commit:

    Date: Sat, 9 Jul 2011 22:05:22 +0800
    [BUILTIN] Merge SKIPFUNC/SKIPFILE and only clear SKIPFUNC when leaving dotcmd

    Currently upon leaving a dotcmd the evalskip state is reset so
    if a continue/break statement is used within a dot script it would
    have no effect outside of the dot script.

    This is inconsistent with other shells.

    This patch is based on one by Jilles Tjoelker and only clears
    SKIPFUNC when leaving a dot script.  As a result continue/break
    will remain in effect.

    It also merges SKIPFUNC/SKIPFILE as they have no practical difference.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-30 14:46:41 +02:00
Denys Vlasenko
ed6ff5edfc hush: enable "msh is deprecated" message in msh stub
After giving a few more years for everyone to notice and migrate,
can nuke all remains of msh.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-30 12:28:37 +02:00
Denys Vlasenko
50e6d42c19 ash: Avoid overflow for very long variable name
Upstream commit:

    Date: Tue, 3 Jul 2012 17:32:33 +0800
    Avoid overflow for very long variable name

    Otherwise, this:
      $ perl -le 'print "v"x(2**31+1) ."=1"' | dash
    provokes integer overflow

    Signed-off-by: Jim Meyering <meyering@redhat.com>
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-30 11:35:54 +02:00
Denys Vlasenko
b6838b520a ash: [VAR] Sanitise environment variable names on entry
Upstream commit:

    Date: Sat, 25 Feb 2012 15:35:18 +0800
    [VAR] Sanitise environment variable names on entry

    On Tue, Feb 14, 2012 at 10:48:48AM +0000, harald@redhat.com wrote:
    > "export -p" prints all environment variables, without checking if the
    > environment variable is a valid dash variable name.
    >
    > IMHO, the only valid usecase for "export -p" is to eval the output.
    >
    > $ eval $(export -p); echo OK
    > OK
    >
    > Without this patch the following test does error out with:
    >
    > test.py:
    > import os
    > os.environ["test-test"]="test"
    > os.environ["test_test"]="test"
    > os.execv("./dash", [ './dash', '-c', 'eval $(export -p); echo OK' ])
    >
    > $ python test.py
    > ./dash: 1: export: test-test: bad variable name
    >
    > Of course the results can be more evil, if the environment variable
    > name is crafted, that it injects valid shell code.

    This patch fixes the issue by sanitising all environment variable names
    upon entry into the shell.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-30 11:33:47 +02:00
Denys Vlasenko
a2d121cc1b ash: [EVAL] Avoid using undefined handler
Upstream commit:

    Date: Fri, 8 Jul 2011 16:41:24 +0800
    [EVAL] Avoid using undefined handler

    * src/eval.c (evalbltin, evalfun): Set savehandler before calling
    setjmp with the possible "goto *done", where savehandler is used.
    Otherwise, clang warns that "Assigned value is garbage or undefined"
    at the point where "savehandler" is used on the RHS.

    Signed-off-by: Jim Meyering <meyering@redhat.com>
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-30 11:30:11 +02:00
Denys Vlasenko
53d6e03a0a ash: remove dead stores and unused variables
Upstream commit 1:

    Date: Fri, 8 Jul 2011 16:12:20 +0800
    [MEMALLOC] Avoid gcc warning: variable 'oldstackp' set but not used

    * src/memalloc.c (growstackblock): Remove declaration and set of
    set-but-not-used variable.  Also remove a stray space-before-TAB.

    Signed-off-by: Jim Meyering <meyering@redhat.com>
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Upstream commit 2:

    Date: Fri, 8 Jul 2011 16:16:11 +0800
    [MEMALLOC] Avoid clang warning about dead store to "size"

    * src/memalloc.c (makestrspace): Remove dead store.

    Signed-off-by: Jim Meyering <meyering@redhat.com>
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-30 11:24:12 +02:00
Denys Vlasenko
60ca834358 ash: [MEMALLOC] Add pushstackmark
Upstream commit:

    Author: Herbert Xu <herbert@gondor.apana.org.au>
    Date:   Sat Oct 6 00:45:52 2007 +0800

    [MEMALLOC] Add pushstackmark

    This patch gets rid of the stack mark tracking hack by allocating a little
    bit of stack memory if we're at risk of planting a stack mark which may be
    grown later.  To do this a new function pushstackmark is added which lets
    the user pick a bigger amount to allocate since some users do that anyway
    after setting a stack mark.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-30 11:21:21 +02:00
Denys Vlasenko
08755f9bcb hush: fix typo in comment
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-30 02:02:25 +02:00
Denys Vlasenko
4074d49557 hush: fix interactive input handling of backslash+newline
function                                             old     new   delta
fgetc_interactive                                      -     258    +258
i_peek_and_eat_bkslash_nl                             43      93     +50
static_peek2                                           7       -      -7
setup_string_in_str                                   46      39      -7
setup_file_in_str                                     47      40      -7
file_peek                                             72      52     -20
expand_vars_to_list                                 1167    1143     -24
file_peek2                                            74       -     -74
file_get                                             326      65    -261
------------------------------------------------------------------------------
(add/remove: 1/2 grow/shrink: 1/5 up/down: 308/-400)          Total: -92 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-30 01:49:53 +02:00
Denys Vlasenko
0448c55cc8 hush: G.user_input_buf[] is needed only if line editing is enabled
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-29 20:25:44 +02:00
Denys Vlasenko
7a24e8ffeb shell testsuite: add trailing newline to var_unbackslash1.tests
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-29 20:02:53 +02:00
Denys Vlasenko
46e6498b2a hush: speed optimizations
Make o_addchr() faster: do not call o_grow_by() each time.
Create i_getch_and_eat_bkslash_nl(), use it instead of peek+getch pair.

function                                             old     new   delta
o_addchr                                              42      54     +12
parse_dollar                                         761     771     +10
o_grow_by                                             48      37     -11
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/1 up/down: 24/-11)             Total: 11 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-29 19:50:55 +02:00
Denys Vlasenko
657086a3dc hush: fix handling of by backslash-newline in $((arith)) and $(cmd)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-29 18:07:42 +02:00
Denys Vlasenko
d17a91db6e hush: rework input char buffering to allow more than one-deep peek
...this time with actual hush.c changes too :)

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-29 18:02:37 +02:00
Denys Vlasenko
459293b1c5 ash: fix arithmetic closing )) split by backslash-newline
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-29 17:58:58 +02:00
Denys Vlasenko
73c3e074df ash: [PARSER] Handle backslash newlines properly after dollar sign
Fixes var_unbackslash1.tests failure.

Upstream commit:

    [PARSER] Handle backslash newlines properly after dollar sign

    On Tue, Aug 26, 2014 at 12:34:42PM +0000, Eric Blake wrote:
    > On 08/26/2014 06:15 AM, Oleg Bulatov wrote:
    > > While playing with sh generators I found that dash and bash have different
    > > interpretations for <slash><newline> sequence.
    > >
    > > $ dash -c 'EDIT=xxx; echo $EDIT\
    > >> OR'
    > > xxxOR
    >
    > Buggy.
    > >
    > > $ dash -c 'echo "$\
    > > (pwd)"'
    > > $(pwd)
    > >
    > > Is it undefined behaviour in POSIX?
    >
    > No, it's well-defined, and dash is buggy.
    ...

    I agree.  This patch should resolve this problem and similar ones
    affecting blackslash newlines after we encounter a dollar sign.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-29 17:17:04 +02:00
Denys Vlasenko
8286513838 hush: rework input char buffering to allow more than one-deep peek
This fixes backslash+newline continuation in
	$VAR\
	NAME
construct. (ash has a bug there as well).

function                                             old     new   delta
file_peek2                                             -      74     +74
parse_dollar                                         746     773     +27
expand_vars_to_list                                 1143    1167     +24
setup_string_in_str                                   32      46     +14
setup_file_in_str                                     33      47     +14
file_get                                             264     278     +14
static_peek2                                           -       7      +7
file_peek                                             91      72     -19
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 5/1 up/down: 174/-19)           Total: 155 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-29 16:59:06 +02:00
Denys Vlasenko
3b4d04b77e ash: input: Allow two consecutive calls to pungetc
Upstream commit:

    input: Allow two consecutive calls to pungetc

    The commit ef91d3d6a4c39421fd3a391e02cd82f9f3aee4a8 ([PARSER]
    Handle backslash newlines properly after dollar sign) created
    cases where we make two consecutive calls to pungetc.  As we
    don't explicitly support that there are corner cases where you
    end up with garbage input leading to undefined behaviour.

    This patch adds explicit support for two consecutive calls to
    pungetc.

    Reported-by: Jilles Tjoelker <jilles@stack.nl>
    Reported-by: Juergen Daubert <jue@jue.li>
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

In bbox case, bashism >& may need two pungetc() too.

function                                             old     new   delta
pgetc                                                514     555     +41
pushstring                                           114     144     +30
basepf                                                52      76     +24
popstring                                            134     151     +17
parse_command                                       1584    1585      +1
pungetc                                               12       9      -3
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 5/1 up/down: 113/-3)            Total: 110 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-29 02:11:19 +02:00
Denys Vlasenko
78c9c736ab hush: fix 'eval ""' handling
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-29 01:44:17 +02:00
Denys Vlasenko
992e0ff7e9 hush: fix ". EMPTY_LINE" not setting $? to 0
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-29 01:27:09 +02:00
Denys Vlasenko
46a45ce02f ash: jobs: Don't attempt to access job table for job %0
Upstream commit:

    jobs: Don't attempt to access job table for job %0

    If job %0 is (mistakenly) specified, an out-of-bounds access to the
    jobtab occurs in function getjob() if num = 0:

            jp = jobtab + 0 - 1

    Fix this by checking that the job number is larger than 0 before
    accessing the jobtab.

    Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-29 01:10:08 +02:00
Denys Vlasenko
928e2a7ef4 ash: [EVAL] Make eval with empty arguments return 0
This is a backport of upstream commit:

    [EVAL] Make eval with empty arguments return 0

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-29 00:30:31 +02:00
Denys Vlasenko
8e2bc47d62 ash: [EVAL] Fix use-after-free in dotrap/evalstring
From upstream:

    [EVAL] Fix use-after-free in dotrap/evalstring

    The function dotrap calls evalstring using the stored trap string.
    If evalstring then unsets that exact trap string then we will end
    up using freed memory.

    This patch fixes it by making evalstring always duplicate the string
    before using it.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-28 23:02:57 +02:00
Denys Vlasenko
7ee7c6fc20 ash: Remove unused EV_BACKCMD flag
The original ash defered forking commands in backquotes so builtins
    could be run in the same context as the shell.  This behavior was
    controlled using the EV_BACKCMD to evaltree.

    Unfortunately, as Matthias Scheler noticed in 1999 (NetBSD PR/7814),
    the result was counterintuitive; for example, echo "`cd /`" would
    change the cwd.  So ash 0.3.5 left out that optimization.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-28 19:44:16 +02:00
Denys Vlasenko
eb17b6f6c9 ash: eval: Return status in eval functions
Backported from dash:

    eval: Return status in eval functions

    The exit status is currently clobbered too early for case statements
    and loops.  This patch fixes it by making the eval functions return
    the current exit status and setting them in one place -- evaltree.

    Harald van Dijk pointed out a number of bugs in the original patch.

function                                             old     new   delta
evalcommand                                         1226    1242     +16
cmdloop                                              383     398     +15
evalfor                                              223     227      +4
evalcase                                             271     275      +4
localcmd                                             348     350      +2
evaltreenr                                           927     928      +1
evaltree                                             927     928      +1
evalsubshell                                         150     151      +1
evalpipe                                             356     357      +1
parse_command                                       1585    1584      -1
evalloop                                             177     164     -13
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 9/2 up/down: 45/-14)             Total: 31 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-28 19:41:57 +02:00
Denys Vlasenko
557482c1cb ash: in heredoc code, fix access past the end of allocated memory. Closes 9276
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-25 21:24:04 +02:00
Denys Vlasenko
13f20919b2 ash: fix handling of NULs in $'abc\000def\x00asd'. Closes 9286
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-25 20:54:25 +02:00
Denys Vlasenko
b3f29b452a ash: use glob() from libc
Adapted from dash.
The "homegrown" glob code is retained (ifdef'ed out).
This changes was inspired by bug 9261, which detected out-of bounds use of heap
for 2098 byte long name in the "homegrown" code. This is still not fixed...

function                                             old     new   delta
expandarg                                            960     982     +22
static.syntax_index_table                             26      25      -1
static.spec_symbls                                    27      26      -1
static.metachars                                       4       -      -4
addfname                                              42       -     -42
msort                                                126       -    -126
expmeta                                              528       -    -528
------------------------------------------------------------------------------
(add/remove: 0/4 grow/shrink: 1/2 up/down: 22/-702)          Total: -680 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-21 16:25:58 +02:00
Denys Vlasenko
244fdd45c7 ash: fix handling of bashism $'xxx' with high-bit chars. Closes 9236
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-20 17:04:09 +02:00
Denys Vlasenko
d6a37d86ba hush: document better where bad redirect syntax is detected
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-20 16:22:24 +02:00
Rostislav Skudnov
204c7fb229 ash: exit after subshell error when errexit option is set
When "set -e" option is on, shell must exit when any command fails,
including compound commands of the form (compound-list) executed in a
subshell. Bash and dash shells have this behaviour.

Also add a corresponding testcase.

Signed-off-by: Rostislav Skudnov <rostislav@tuxera.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-17 23:28:23 +02:00
Denys Vlasenko
7373759947 fix "aloc" -> "alloc" typos
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-17 20:58:22 +02:00
Denys Vlasenko
7bc3d39695 ash: add a FIXME for bug 9246
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-17 20:53:47 +02:00
Denys Vlasenko
ef15970d7e *: placate some compile warnings on OSX
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-09-01 11:16:22 +02:00
Denys Vlasenko
aa3576a29b hush: fix "redirects can close script fd" bug
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-08-22 19:54:12 +02:00
Denys Vlasenko
7b25b1c5b2 hush: do not leak script fds into NOEXEC children
We set all opened script fds to CLOEXEC, thus making then go away
after fork+exec.
Unfortunately, CLOFORK does not exist. NOEXEC children will still see those fds open.

For one, "ls" applet is NOEXEC. Therefore running "ls -l /proc/self/fd"
in a script from standalone shell shows this:

lrwx------    1 root     root            64 Aug 20 15:17 0 -> /dev/pts/3
lrwx------    1 root     root            64 Aug 20 15:17 1 -> /dev/pts/3
lrwx------    1 root     root            64 Aug 20 15:17 2 -> /dev/pts/3
lr-x------    1 root     root            64 Aug 20 15:17 3 -> /path/to/top/level/script
lr-x------    1 root     root            64 Aug 20 15:17 4 -> /path/to/sourced/SCRIPT1
...

with as many open fds as there are ". SCRIPTn" nest levels.
Fix it by closing these fds after fork (only for NOEXEC children).

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-08-20 15:58:34 +02:00
Denys Vlasenko
869994cf4f hush: bit better comments in redirect code. No logic changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-08-20 15:16:00 +02:00
Denys Vlasenko
e9abe75fda hush: cmd and arithmetic also need the fix for FILE rewind
Discovered by running testsuite with a newest glibc

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-08-19 20:15:26 +02:00
Denys Vlasenko
215b0ca6e4 hush: fix a bug in FEATURE_SH_STANDALONE=y config. Closes 9186
Run this in a "sh SCRIPT":

sha256sum /dev/null
echo END

sha256sum is a NOEXEC applet. It runs in a forked child. Then child exit()s.
By this time, entire script is read, and buffered in a FILE object
from fopen("SCRIPT"). But fgetc() did not consume entire input.
exit() lseeks back by -9 bytes, from <eof> to 'e' in 'echo'.
(this may be libc-specific).
This change of fd position *is shared with the parent*!

Now parent can read more, and it thinks there is another "echo END".
End result: two "echo END"s are run.

Fix this by _exit()ing instead.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-08-19 18:43:06 +02:00