NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
standards/42828: Almquist shell always evaluates the contents of ${ENV} even if non-interactive
>Number: 42828
>Category: standards
>Synopsis: Almquist shell always evaluates the contents of ${ENV} even if
>non-interactive
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: standards-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Feb 16 17:55:00 +0000 2010
>Originator: Richard Hansen
>Release: 5.0
>Organization:
>Environment:
NetBSD deer-netbsd.bbn.com 5.0_STABLE NetBSD 5.0_STABLE (GENERIC) #4: Tue Feb
2 10:43:58 EST 2010
gdt%fnord.ir.bbn.com@localhost:/n0/obj/gdt-5/amd64/sys/arch/amd64/compile/GENERIC
amd64
>Description:
NetBSD 5.0's /bin/sh always evaluates the contents of the file identified by
${ENV} even if the shell is non-interactive. This has a few consequences:
* NetBSD's /bin/sh is not compliant with POSIX:2004 [1] or POSIX:2008 [2] (at
least)
* shell script execution is unnecessarily slow if the ${ENV} file does a lot
of stuff
* if the ${ENV} file executes a shell script, or executes something that
executes a shell script, you'll get a fork bomb
[1]
<http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_05_03>
[2]
<http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_03>
>How-To-Repeat:
$ printf '#!/bin/sh\necho bar\n' > bar
$ chmod a+x bar
$ echo './bar' > foo
$ ENV=$(pwd)/foo /bin/sh -i
./bar: Cannot vfork
bar
bar
bar
bar
^C
$
>Fix:
The following patch is completely untested (I haven't even compiled it yet).
I'm not sure when iflag is initialized, so this may not be the correct fix:
Index: bin/sh/main.c
===================================================================
RCS file: /cvsroot/src/bin/sh/main.c,v
retrieving revision 1.53
diff -u -p -r1.53 main.c
--- bin/sh/main.c 18 Jan 2009 00:30:54 -0000 1.53
+++ bin/sh/main.c 8 Feb 2010 06:08:26 -0000
@@ -184,7 +184,7 @@ state1:
}
state2:
state = 3;
- if (getuid() == geteuid() && getgid() == getegid()) {
+ if (iflag && getuid() == geteuid() && getgid() == getegid()) {
if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
state = 3;
read_profile(shinit);
Home |
Main Index |
Thread Index |
Old Index