the behavior of sh xxx.sh

64 views
Skip to first unread message

haomiao

unread,
Dec 9, 2009, 10:34:19 PM12/9/09
to
Hi
I am using ksh, and I found that when use
sh xxx.sh
to execute xxx.sh, the sh will first look up PATH, when
there is no xxx.sh in PATH, sh will look up current directory even the
current directory is not in PATH.

I read the manual of ksh and can not find the description of
the above behavior. The manual just says in "Invocation" section that
sh will look up PATH, and not says the current directory.

Will anyone tell me where is the desciption in the manual of
the above behavior, or is it a no documented behavior?

Janis

unread,
Dec 9, 2009, 11:13:09 PM12/9/09
to
On Dec 10, 4:34 am, haomiao <miaoh...@ustc.edu> wrote:
> Hi
> I am using ksh, and I found that when use
> sh xxx.sh
> to execute xxx.sh, the sh will first look up PATH,

Are you sure about that? It shouldn't inspect PATH because it's just
passed to sh as argument.

> when
> there is no xxx.sh in PATH, sh will look up current directory even the
> current directory is not in PATH.

This is correct, because you're providing xxx.sh as argument to sh.

It would be different if you have made xxx.sh executable (chmod +x)
and call it directly (i.e. without the interpreter sh) as

xxx.sh

>
> I read the manual of ksh and can not find the description of
> the above behavior.

It should make sense if you check your first testcase again.

Janis

haomiao

unread,
Dec 10, 2009, 1:33:11 AM12/10/09
to
I did some test, the result is

---------------------------------------------------------------
test$ mkdir d1
test$ export PATH=/usr/bin
test$ echo "echo this is d1/t1.sh" >d1/t1.sh
test$ sh t1.sh
sh: t1.sh: not found
test$ export PATH=/usr/bin:/posapp/usr/upas3/d1
test$ sh t1.sh
sh: t1.sh: cannot execute
test$ chmod u+x d1/t1.sh
test$ sh t1.sh
this is d1/t1.sh
test$ echo "echo this is ./t1.sh" >t1.sh
test$ sh t1.sh
this is d1/t1.sh
test$ chmod u-x d1/t1.sh
test$ sh t1.sh
this is ./t1.sh
test$ rm d1/t1.sh
test$ sh t1.sh
this is ./t1.sh
------------------------------------------------------------------------------

It seems "sh xxx.sh" will look up PATH(need x mode), then current
dir(need no x mode).

Geoff Clare

unread,
Dec 10, 2009, 8:56:23 AM12/10/09
to
Janis wrote:

> On Dec 10, 4:34 am, haomiao <miaoh...@ustc.edu> wrote:
>> Hi
>> I am using ksh, and I found that when use
>> sh xxx.sh
>> to execute xxx.sh, the sh will first look up PATH,
>
> Are you sure about that? It shouldn't inspect PATH because it's just
> passed to sh as argument.

POSIX requires that the shell tries to read from the named file
first, but if the file does not exist it is optional whether the
shell then does a PATH search.

--
Geoff Clare <net...@gclare.org.uk>


Janis

unread,
Dec 10, 2009, 12:59:26 PM12/10/09
to
On Dec 10, 4:34 am, haomiao <miaoh...@ustc.edu> wrote:

My ksh seems to have documented it in its built-in man page...

ksh --man

The relevant part...

If the neither -s nor -c is specified, then the first arg
will be the pathname of the file containing commands and $0
will be set to this value. If there is no file with this
pathname, and this pathame does not contain a /, then the
PATH will be searched for an executable with this name. Any
remaining args will be used to initialize the positional
parmaeters.

Thanks, Geoff, for the POSIX hint.

Janis

Stephane CHAZELAS

unread,
Dec 10, 2009, 2:42:35 PM12/10/09
to
2009-12-9, 19:34(-08), haomiao:

Old versions of ksh had this bug that was also a security hole
on systems that support setuid scripts (and don't implement it
like in Solaris with some /dev/fd/x)

Some ksh based sh's still have that bug.

Newer versions of ksh93 are fixed. IIRC ksh88i had the bug and
some vendors have fixed it.

--
Stï¿œphane

Jon LaBadie

unread,
Dec 10, 2009, 3:15:21 PM12/10/09
to
What are you referring to as a "bug"? The execution of the filename
argument in the current directory even if it is not included in PATH?

If so, I still see that behavior (not sure if I think of it as a bug)
in recent releases of ksh93.

haomiao

unread,
Dec 11, 2009, 1:16:01 AM12/11/09
to
Thanks for all!

I finally have knowledges that
1. In POSIX, first the current directory, then the PATH.
2. Not all shell comply with this POSIX rule.
3. In my environment (ksh88 in AIX6.1), first PATH, then current
directory.

Stephane CHAZELAS

unread,
Dec 11, 2009, 2:38:48 AM12/11/09
to
2009-12-10, 22:16(-08), haomiao:

Yes, and to clarify the security hole, if you have a setuid ksh
script (for instance /opt/x/bin/foo starting with #! /bin/ksh
-)), one can make another script by the same name and put it in
$PATH (like echo sh > ~/bin/foo; chmod +x ~/bin/foo), then

chdir("/opt/x/bin");
execl("foo", "foo", 0);

Then the system will change that to:

execl("/bin/ksh", "ksh" (or "foo" depending on the system), "-",
"foo", 0); (*)

With the process euid being the owner of /opt/x/bin/foo

But ksh will interpret ~/bin/foo instead of /opt/x/bin/foo
because ~/bin is in $PATH and not /opt/x/bin

(*) Some systems will change it instead to
execl("/bin/ksh", "ksh" (or "foo" depending on the system), "-",
"/dev/fd/3", 0);
where fd 3 is open to /opt/x/bin/foo. That fixes both that hole
and the race condition one.

Note that not all systems support setuid scripts, and on some,
the support can be disabled/enabled at run time.

In any case, a setuid shell script especially a ksh one is most
likely to be a security hole, one should avoid that at all cost.

--
Stï¿œphane

Reply all
Reply to author
Forward
0 new messages