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);
