[comp.lang.perl] Setuid/setgid scripts

pem@frankland-river.aaii.oz.au (Paul E. Maisano) (03/25/90)

I am trying to run a perl script setgid but have had some problems.

I am running perl under SUNOS 4.0, so scripts are insecure.
Perl reminded me of this loudly after I made the script setgid.

I don't know how to disable setuid/setgid scripts in the kernel (but
would be interested in finding out). Also I don't have the undump program
handy. So I decided I would simply put a setgid C wrapper around the script.
Something like:
    main(ac, av)
    char **av;
    {
	execv("/usr/local/bin/script", av);
    }

I tried this without changing the mode of the wrapper to be setgid. It ran
ok but without access to the files I needed, as expected.
As soon as I made the wrapper setgid, perl started dumping core.
It stopped dumping core after I added the following line before the execv.
    setrgid(getegid());

Can anyone enlighten me about this ?

This wrapper is still no good but it's not perl's fault. The documented
behaviour of setrgid() on my system (and most other UNIXes, I believe)
is to take away the access privileges which you had by virtue of the
group you are leaving.

So in other words, this wrapper allows me to access the files I could
not access before but denies me access to some files which I used to
have access to before.

I can't seem to get this working cleanly, so I was wondering if anyone
had any ideas.
 
My current solution is to make the C-wrapper setuid-root as well, so that
it can preserve the original group access list. But it seems like overkill
to have to make it setuid-root.

#include <sys/param.h>

char err[] = "exec failed\n";
int  groups[NGROUPS];

main(ac, av)
char    **av;
{
    int n = getgroups(NGROUPS, groups);
    setrgid(getegid());
    setgroups(n, groups);
    setuid(getuid());
    execv("/usr/local/bin/script", av);
    write(2, err, sizeof err);
}

------------------
Paul E. Maisano
Australian Artificial Intelligence Institute
1 Grattan St. Carlton, Vic. 3053, Australia
Ph: +613 663-7922  Fax: +613 663-7937
Email: pem@aaii.oz.au   UUCP: {uunet,mcsun,ukc,nttlab}!munnari!aaii.oz.au!pem

piet@cs.ruu.nl (Piet van Oostrum) (03/26/90)

In article <1395@frankland-river.aaii.oz.au>, pem@frankland-river (Paul E. Maisano) writes:
 `
 `I am trying to run a perl script setgid but have had some problems.
 `
 `I am running perl under SUNOS 4.0, so scripts are insecure.
 `Perl reminded me of this loudly after I made the script setgid.
 `
We also have a system where perl complains about insecure scripts. We got
rid of this by #!-ing not perl but suidperl. I know Larry says that
suidperl is not meant to be called directly, but this worked. Of course the
resulting system is insecure, but if you can live with that ...
-- 
Piet* van Oostrum, Dept of Computer Science, Utrecht University,
Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands.
Telephone: +31-30-531806   Uucp:   uunet!mcsun!ruuinf!piet
Telefax:   +31-30-513791   Internet:  piet@cs.ruu.nl   (*`Pete')

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (03/27/90)

In article <1395@frankland-river.aaii.oz.au> pem@frankland-river.aaii.oz.au (Paul E. Maisano) writes:
: 
: I am trying to run a perl script setgid but have had some problems.
: 
: I am running perl under SUNOS 4.0, so scripts are insecure.
: Perl reminded me of this loudly after I made the script setgid.
: 
: I don't know how to disable setuid/setgid scripts in the kernel (but
: would be interested in finding out). Also I don't have the undump program
: handy. So I decided I would simply put a setgid C wrapper around the script.
: Something like:
:     main(ac, av)
:     char **av;
:     {
: 	execv("/usr/local/bin/script", av);
:     }
: 
: I tried this without changing the mode of the wrapper to be setgid. It ran
: ok but without access to the files I needed, as expected.
: As soon as I made the wrapper setgid, perl started dumping core.

This is odd, because I just ran a setgid script here with no problem.  The
script says

	#!/usr/bin/perl
	print "$(\n$)\n";

I wrapped it with a wrapper very much like the one above, and it works fine.
I run it and it says

	20 35 10 3 0 20
	25 35 10 3 0 20

I'm running it under SunOS 4.0.3.

: It stopped dumping core after I added the following line before the execv.
:     setrgid(getegid());

I don't need that here, as you can tell by the values above.  BTW, I didn't
compile with DOSUID, if that makes any difference.

Larry

pem@yarra-glen.aaii.oz.au (Paul E. Maisano) (03/27/90)

In article <7557@jpl-devvax.JPL.NASA.GOV>, lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes:
> 
> This is odd, because I just ran a setgid script here with no problem.  The
> script says
> 
> 	#!/usr/bin/perl
> 	print "$(\n$)\n";
> 
> I wrapped it with a wrapper very much like the one above, and it works fine.
> I run it and it says
> 
> 	20 35 10 3 0 20
> 	25 35 10 3 0 20
> 
> I'm running it under SunOS 4.0.3.

Ok, things are starting to look interesting...

I'm running it under 4.0.3 as well, on a Sparcstation-1.

I've narrowed it down to the following weirdness -- it looks like it has
something to do with uninitialized array elements but I don't understand
why having the effective group id different from the real gid triggers it.

Here is how I repeat it:

I have a perl script called 'bug' and a C-wrapper which runs './bug'.
I compile the C wrapper, and run it and it works fine.
I do a "chmod g+s a.out" (or whatever I compiled the wrapper into) and it
causes a segmentation fault when I run it.

-------cut here for C-wrapper----------
main(ac, av)
char    **av;
{
    execv("./bug", av);
}
-------cut here for perl-program called 'bug'-----
#!/usr/bin/perl
 
warn "$(\n$)\n";

$array[1] = "y";
$var = " @array ";              # this line dumps core when egid != rgid
print "var=<$var>\n";
-------cut here------

Making the real group id the same as the effective gid fixes it, whether by
not making the wrapper setgid or by adding "setrgid(getegid());" before
the call to execv().

The work around is obvious; just make sure you have no uninitialized
array elements. 

If this is a weird bug with uninitialized array elements I can't wait
to hear why the effective group id has something to do with it.

BTW, How do you disable setuid shell scripts in the kernel? The perl manual
seems to imply that it is a straightforward thing to do.

------------------
Paul E. Maisano
Australian Artificial Intelligence Institute
1 Grattan St. Carlton, Vic. 3053, Australia
Ph: +613 663-7922  Fax: +613 663-7937
Email: pem@aaii.oz.au   UUCP: {uunet,mcsun,ukc,nttlab}!munnari!aaii.oz.au!pem

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (03/28/90)

In article <1400@yarra-glen.aaii.oz.au> pem@yarra-glen.aaii.oz.au (Paul E. Maisano) writes:
: I've narrowed it down to the following weirdness -- it looks like it has
: something to do with uninitialized array elements but I don't understand
: why having the effective group id different from the real gid triggers it.
: 
...
: 
: Making the real group id the same as the effective gid fixes it, whether by
: not making the wrapper setgid or by adding "setrgid(getegid());" before
: the call to execv().
: 
: The work around is obvious; just make sure you have no uninitialized
: array elements. 
: 
: If this is a weird bug with uninitialized array elements I can't wait
: to hear why the effective group id has something to do with it.

Because if the effective and real group id are the same, perl doesn't call
taintperl to interpret the script.

The bug arises in some code that is trying to propagate "taintedness", so
if you don't run taintperl, you don't exercise it.

: BTW, How do you disable setuid shell scripts in the kernel? The perl manual
: seems to imply that it is a straightforward thing to do.

It is if you have the sources.  Or if Sun would get off their corporate duff
and insert two lines of code depending on an adb-able variable.  But they
won't unless a lot of people make some noise.  We don't weigh enough,
apparently.  Anyway, I just got the usual sunaround, er, I mean, runaround.

ARE YOU LISTENING, SUN?

Now, it turns out to be a simple binary patch on a Vax, because you can
just change a branch.  But on a Sun, you'd have to insert some code, and
I've never developed the patch.

If you have the sources, the patch was sent out by Berkeley long ago, and
you can find it in one of their official patch repositories.  Sun claims
the patch was not "mandatory".

Do we need to fill up the hotline's mailbox?  I don't like being nasty...

Larry