Re: discarding root privileges in suid perl
>>>>> "Daniel" == Daniel Jacobowitz <dan@debian.org> writes:
Daniel> I would expect this to be something to do with saved
Daniel> userids... see setresuid(2) for more information:
Yes, I think you might be correct.
Daniel> Unprivileged user processes (i.e., processes with
Daniel> each of real, effective and saved user ID nonzero) may
Daniel> change the real, effective and saved user ID, each to one
Daniel> of: the current uid, the current effective uid or the
Daniel> current saved uid.
Daniel> The super-user may set real, effective and saved
Daniel> user ID to arbitrary values.
Daniel> It's not clear what happens when saved uid is zero and the
Daniel> others are nonzero, but I bet that's what you're seeing.
Daniel> Note that saved uid is -not- preserved across exec() IIRC.
Daniel> So if you drop priviledges and then run a script that
Daniel> tries to get them back, it will fail, even if the parent
Daniel> could.
This sounds correct. Where did you find this documented? I tried
looking up the functions in the info documentation for libc, but it
doesn't seem to contain anything (that I could find).
>From the messages <ufa4s42bca7.fsf@epithumia.math.uh.edu> in
comp.lang.perl.moderated on deja.com,
--- cut ---
>...
>I think the real bug here, if there's one that can be easily identified,
>is that POSIX::setuid() isn't actually setuid() like it should be.
I agree. I was "on" POSIX::setuid() a long time ago. If it had been implemented to call setuid(),
that would have been the end of the matter. Oh well...
I think that perl is trying to do The Right Thing when you code:
$> = $id;
$< = $id;
and it does relinquish root when this is done on Solaris. The
documentation is far from clear about this, though and the perlsec manual page is just plain
wrong since it never assigns to $< to drop privileges.
--- cut ---
So, perhaps somebody should file a bug report against the perlsec man
page. My guess, is its advice is non-portable, and only works on some
platforms.
I would file a bug report, but I am getting totally confused, and not
sure I could justify the reasons why the example is incorrect. I will
try here. I don't claim this is accurate or anything...
--- cut & [mis]interpreted ---
So, the following functions, as implemented in the kernel would
look something like this???? I have prefixed kernel variables
with "k" to make them different from the perl values.
setuid {
my ($uid) = @_;
if ($kEUID == 0) { $kUID=$kEUID=$ksaved=$uid; }
elsif ($kEUID == $kUID or $kEUID == $ksaved) { $kEUID=$uid; }
}
seteuid {
my ($uid) = @_;
??????
}
setreuid {
my ($uid,$X) = @_;
($kUID,$kEUID) = ($kEUID,$kUID);
if ($saved != $kUID) { $saved = $kEUID; }
}
--- cut & [mis]interpreted ---
So debugging the code in the man page (I won't worry about groups):
initially:
$saved=?; $EUID = 0; $UID=1003;
print("$EUID $UID");
>> prints 0 1003
my @temp = ($EUID);
>>> @temp = (0);
$EUID = $UID;
>>> seteuid(1003);
>>> $kEUID = 1003;
>>> $EUID = 1003;
print("$EUID $UID");
>> prints 1003 1003
($EUID) = @temp;
>>> seteuid(0);
>>> $kEUID = 0
>>> $kUID = 0
print("$EUID $UID");
>> prints 0 1003
So I am still a bit of a loss, and I am not sure how seteuid works.
Either:
- $saved initially is 0 and not affected by the seteuid(1003).
OR:
- $saved is set to 0 by seteuid(1003) possibly because $EUID was
previous 0.
I hope some of this makes sense to someone :-)
Just to confuse matters even more:
ps xf -eo pid,ppid,uid,euid,fuid,fsuid,svuid,suid,ruid,ucmd | less
don't ask me what all of these mean ;-)
ruid != uid
uid == euid == fuid == fsuid generally
svuid == suid == ruid except for:
PID PPID UID EUID FUID FSUID SVUID SUID RUID CMD
566 1 1 1 1 1 1 1 0 atd
21980 1 109 109 109 109 109 109 109 rproxy
4028 21980 109 109 109 109 109 109 0 \_ rproxy <defunct>
4030 21980 109 109 109 109 109 109 0 \_ rproxy <defunct>
4032 21980 109 109 109 109 109 109 0 \_ rproxy <defunct>
4033 21980 109 109 109 109 109 109 0 \_ rproxy <defunct>
27266 1 1003 1003 1003 1003 1003 1003 1003 gnome-terminal
27268 27266 1003 1003 1003 1003 1003 1003 1003 \_ zsh
4362 27268 0 0 0 0 0 0 1003 \_ perl5.00503
4391 4362 0 0 0 0 0 0 1003 \_ tail
which, too me, doesn't make any sense what-so-ever. Why does rproxy,
which is *not* a setuid program, have ruid==0?
The last process is mine, where $UID=0, $EUID=1003, as shown by a perl
print statement, before calling system("tail")). So I guess
RUID=real user
UID=somethingelse
EUID=effective user
SUID=saved UID???
Note:
[1] Is this the same on Linux? I have Linux 2.2.17, final version.
--
Brian May <bam@debian.org>
Reply to: