Have been investigating CR 6934836.

6934836 set-uid script with -p in magic number gets Exec format error
http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6934836

Have a few questions I'm hoping the ksh93 folks here will be able
to help me with.

It looks like the bug is due to the fact that set-uid scripts get
passed to the shell as a /dev/fd/XX parameter instead of the actual
path.  This has problems with ksh93 *only* if there are any options
passed on the command line.

The test program below demonstrates this:

----------

$ cat testexec.c
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int
main()
{
        int fd = -1;
        char devfd[32];
        char *script = "/tmp/ok.ksh";  /* Can be any simple script */

        fd = open(script, O_RDONLY);
        sprintf(devfd, "/dev/fd/%d", fd);
        execl("/usr/bin/sparcv9/ksh93", "ksh", "-v", devfd, NULL);
}
$ ./testexec
/usr/bin/ksh: /usr/bin/ksh: cannot execute [Exec format error]

----------

The culprit seems to be the code below:

<lib/libshell/common/sh/init.c>
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libshell/common/sh/init.c#1216

1216   shp->st.dolv=argv+(argc-1)-shp->st.dolc;
1217   shp->st.dolv[0] = argv[0];

Here, we are overwriting one of the arguments of argv (because
shp->st.dolv indexes into the argv vector).

In this particular case, argv which originally looked like this:

    ksh, -v, /dev/fd/3

ends up looking like this:

    ksh, ksh, /dev/fd/3

We then pass the mangled argv to execv():

<lib/libshell/common/sh/main.c>
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libshell/common/sh/main.c#298

298   /*  exec to change $0 for ps  */
299   execv(pathshell(),av);

As a consequence, ksh tries to load the ksh binary as a shell script and
fails with an "Exec format" error.

Have been digging around trying to figure out what is the right
thing to do in this situation.  Figured some of the people more
familiar with the ksh93 source might be able to help.

Also, the execv() call above uses pathshell() which seems plain wrong.
The whole exec hack here seems to be to make sure $0 is set correctly
for ps.  But pathshell() looks at the SHELL variable and might end up
executing the script with a different shell altogether.

Any help appreciated.

Thanks,
Venky.

Reply via email to