Hi Olga,

> > Venky, does this issue occur even if you bypass isaexec, i.e.

Yes, tried this with /usr/bin/sparcv9/ksh93 to make sure isaexec
does not complicate things.  It does seem to be because of the
arguments getting mangled in line 1217 of libshell/common/sh/init.c.

A quick hack to restore the mangled arguments before exec (patch
attached) seems to fix this issue.  The $0 value remains messed up,
though.  It displays /dev/fd/XX as the script name, while a #! line
without arguments displays the correct script name.

# cat >t1.ksh <<EOF
#!/usr/bin/sparcv9/ksh93 -p
echo \$0
EOF

# cat >t2.ksh <<EOF
#!/usr/bin/sparcv9/ksh93
echo \$0
EOF

# chmod +xs t[12].ksh
# ls -l t*
-rwsr-sr-x 1 root root 36 Mar 24 05:51 t1.ksh
-rwsr-sr-x 1 root root 33 Mar 24 05:51 t2.ksh
# exit

$ ./t1.ksh
/dev/fd/4
$ ./t2.ksh
t2.ksh

Venky.

On Wed, Mar 24, 2010 at 03:13:08AM +0100, ????? ???????????? wrote:
> 2010/3/24 ?????????? ???????????????????????? <olga.kryzhanovska at 
> gmail.com>:
> > Venky, does this issue occur even if you bypass isaexec, i.e.
> > #!/usr/bin/i86/ksh -p
> 
> Correction:
> #!/usr/bin/i86/ksh93 -p
> 
> > or
> > #!/usr/bin/sparcv0/ksh -p
> 
> Correction:
> #!/usr/bin/sparcv9/ksh93 -p
> 
> >
> > Olga
> >
> > On Fri, Mar 19, 2010 at 4:06 PM, Venky <venkytv at opensolaris.org> wrote:
> >> 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.
> >> _______________________________________________
> >> ksh93-integration-discuss mailing list
> >> ksh93-integration-discuss at opensolaris.org
> >> http://mail.opensolaris.org/mailman/listinfo/ksh93-integration-discuss
> >>
> >
> >
> >
> > --
> >      ,   _                                    _   ,
> >     { \/`o;====-    Olga Kryzhanovska   -====;o`\/ }
> > .----'-/`-/     olga.kryzhanovska at gmail.com   \-`\-'----.
> >  `'-..-| /     Solaris/BSD//C/C++ programmer   \ |-..-'`
> >      /\/\                                     /\/\
> >      `--`                                      `--`
> >
> 
> 
> 
> -- 
>       ,   _                                    _   ,
>      { \/`o;====-    Olga Kryzhanovska   -====;o`\/ }
> .----'-/`-/     olga.kryzhanovska at gmail.com   \-`\-'----.
>  `'-..-| /     Solaris/BSD//C/C++ programmer   \ |-..-'`
>       /\/\                                     /\/\
>       `--`                                      `--`
-------------- next part --------------
diff -r b2b3ef1de714 usr/src/lib/libshell/common/include/defs.h
--- a/usr/src/lib/libshell/common/include/defs.h        Thu Mar 18 11:58:31 
2010 +0530
+++ b/usr/src/lib/libshell/common/include/defs.h        Wed Mar 24 18:16:30 
2010 +0530
@@ -93,6 +93,8 @@
        char            **otrapcom;
        void            *timetrap;
        struct Ufunction *real_fun;     /* current 'function name' function */
+       int             repl_index;
+       char            *repl_arg;
 };
 
 struct limits
diff -r b2b3ef1de714 usr/src/lib/libshell/common/sh/init.c
--- a/usr/src/lib/libshell/common/sh/init.c     Thu Mar 18 11:58:31 2010 +0530
+++ b/usr/src/lib/libshell/common/sh/init.c     Wed Mar 24 18:16:30 2010 +0530
@@ -1186,6 +1186,7 @@
        job_clear();
        if(argc>0)
        {
+               int dolv_index = -1;
                /* check for restricted shell */
                if(type&SH_TYPE_RESTRICTED)
                        sh_onoption(SH_RESTRICTED);
@@ -1213,7 +1214,10 @@
                        sh_done(shp,0);
                }
                opt_info.disc = 0;
-               shp->st.dolv=argv+(argc-1)-shp->st.dolc;
+               dolv_index = (argc-1)-shp->st.dolc;
+               shp->st.dolv=argv+dolv_index;
+               shp->st.repl_index = dolv_index;
+               shp->st.repl_arg = argv[dolv_index];
                shp->st.dolv[0] = argv[0];
                if(shp->st.dolc < 1)
                        sh_onoption(SH_SFLAG);
diff -r b2b3ef1de714 usr/src/lib/libshell/common/sh/main.c
--- a/usr/src/lib/libshell/common/sh/main.c     Thu Mar 18 11:58:31 2010 +0530
+++ b/usr/src/lib/libshell/common/sh/main.c     Wed Mar 24 18:16:30 2010 +0530
@@ -292,6 +292,8 @@
                                         * try to undo effect of solaris 2.5+
                                         * change for argv for setuid scripts
                                         */
+                                       if (shp->st.repl_index > 0)
+                                               av[shp->st.repl_index] = 
shp->st.repl_arg;
                                        if(((type = sh_type(cp = av[0])) & 
SH_TYPE_SH) && (!(name = nv_getval(L_ARGNOD)) || !((type = sh_type(cp = name)) 
& SH_TYPE_SH)))
                                        {
                                                av[0] = (type & SH_TYPE_LOGIN) 
? cp : path_basename(cp);

Reply via email to