Bug 92127 - setuid to current euid fails with EPERM
setuid to current euid fails with EPERM
Status: CLOSED NOTABUG
Product: Red Hat Linux
Classification: Retired
Component: kernel (Show other bugs)
9
All Linux
medium Severity medium
: ---
: ---
Assigned To: Arjan van de Ven
Brian Brock
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2003-06-02 19:48 EDT by Damien Miller
Modified: 2007-04-18 12:54 EDT (History)
2 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2003-06-03 06:00:53 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
Example program (234 bytes, text/plain)
2003-06-02 19:50 EDT, Damien Miller
no flags Details

  None (edit)
Description Damien Miller 2003-06-02 19:48:31 EDT
A common idiom to drop all user privileges is to do a seteuid(new_uid) followed
by a setuid(new_uid). The two steps are done to ensure that the saved uid is
also set to new_uid on some (stupid) platforms.

Unfortunately this doesn't work on Linux. A setuid(geteuid()) call will fail
when the euid != cuid.

I am not sure what the motivation for this check is, as it doesn't seems to add
any security (one already has the euid privileges, or lack thereof). To make
matters doubly confusing, the same restriction is *not* applied to setgid, where
setgid(getegid()) works fine.
Comment 1 Damien Miller 2003-06-02 19:50:23 EDT
Created attachment 92099 [details]
Example program

Here is a simple example illustrating the issue. Run this with (uid, euid) as
root, the setuid call will fail.

If one replaces the setuid and seteuid with setgid and setegid, the second call
will succeed.
Comment 2 Alan Cox 2003-06-03 06:00:53 EDT
Your test program is buggy. When you seteuid() you are no longer effectively
root so you lose the capability to setuid() to someone else.

setuid(), then seteuid() 

Alternatively for more flexibility and BSD like behaviour you can use
setreuid()/setresuid()
Comment 3 Damien Miller 2003-06-03 06:45:55 EDT
> Your test program is buggy. When you seteuid() you 
> are no longer effectively root so you lose the 
> capability to setuid() to someone else.

Well, you are not setuid()ing to someone else. You are setuid()ing 
to your current euid. Seeing as how you already have these privileges, 
I can't see how such a restriction could possibly be useful.

I am aware of setresuid(), it is nice but non-standard and not widely 
supported. setreuid() is ambiguous as to the behaviour wrt saved UIDs 
so IMO can't be trusted for portable software.

BSD allows the order shown in the test program and many BSD programs 
use that order to drop privs. This seems like a break in portability 
for zero gain. 
Comment 4 Alan Cox 2003-06-03 07:12:59 EDT
Linux implements POSIX/SYS5 semantics for setuid/setuid and BSD semantics for
the BSD extensions. It has always taken this approach. For portable code you
should only rely on POSIX and SUS defined behaviour I agree.

Note You need to log in before you can comment on or make changes to this bug.