I just discovered this page of Elizabeth Stinson
explaining the the differences between UID, EUID, SUId and FSUID and how they take effect for Linux, BSD, Solaris, and other Unices. Great document!
As backup her page is cited here:
SETUID syscall: modifies userIDs
Access control in Unix systems: based on a process's userIDs
Each process has a set of userIDs and groupIDs
-- these userIDs and groupIDs determine which resources [files, network
ports, ...] that process can access
-- the privileged userIDs and groupIDs allow a process to access
restricted system resources
userID == 0 --> ROOT; process can access all system resources
In some apps, a user process needs extra privileges; e.g. permission to
read or change the password file
"principle of least privilege" == process should DROP those extra privs, ASAP
UID-setting syscalls: offered by UNIX systems; used by a process to raise
& drop its privilege level; poorly designed, not well documented
USER ID MODEL:
- each user has a unique UID
- UID determines which resources a user can access
Each process has 3 UIDs:
(1) real UID: identifies process OWNER
(2) effective UID: used in access control decisions
(3) saved user ID: stores a previous UID so that it can be restored later
Each process has 3 groupIDs:
(1) real GID
(2) effective GID
(3) saved GID
In Linux, each process *also* has:
(1) FSUID
(2) FSGID
--used for access control to the file system
--FSUID usually follows effective UID unless it's explicitly set by the
setfsuid syscall
--FSGID usually follows effective GID unless explicitly set by setfsgid()
When a process is created by FORK, the created process inherits its
parent's UIDs
When a process executes a NEW FILE via EXEC, that executing process keeps
ITS OWN UIDs unless the SETUID in the new file is set.
-- if the SETUID bit is set in the file we're EXECing, then
--> process's EUID == file owner's UID
--> process's SUID == file owner's UID
To drop privilege temporarily, a process will remove the privileged UID
from its EUID but keep it saved as its saved UID (SUID); later the process
can restore the privileges by setting its EUID to its SUID. To drop
privileges permanently a process removes the privileged UID from all three
of its UIDs; thereafter the process cannot restore that privileged access
Bell Labs patented Dennis Ritchie's idea to have a bit to indicate whether
when a file is executed that file should be executed with the privileges
of its owner (normal) or THE INVOKER (setuid bit == 1 for latter case).
Early UNIX: a process had 2 UIDs, RUID & EUID
--Only one syscall, SETUID:
if (EUID == 0)
RUID = ;
EUID = ;
else
EUID = ;
Problem: no way to temporarily drop root privileges only to restore them later
UNIX
/ \
/ \
Sys V BSD
System V: added SUID and SETUEID syscall
SETEUID:
if (EUID == 0)
EUID can be set to any value;
else
EUID can be set to RUID or SUID ONLY
SETUID was modified:
if (EUID != 0)
EUID can be set;
else
EUID = ;
RUID = ;
SUID = ;
Sys V: so if you're not root, you can use SETUID to set EUID and you can
use SETEUID to set EUID = RUID or EUID = SUID; if you ARE root, you can
use SETUID to set EUID, SUID, RUID and you can use SETEUID to set EUID to
anything;
BSD: dropped SETUID, created SETREUID
SETREUID: if (EUID == 0)
RUID = anyUID;
EUID = anyUID;
else
RUID = EUID; OR
EUID = RUID;
POSIX: SETUID can set all three UIDs whether you're root or not
SETRESUID(newRUID,newEUID,newSUID)
-- to call this function, the EUID of the calling process must be ROOT OR
-- each of the 3 params must equal one of the process's 3 UIDs
-- all or nothing effect;
-- FreeBSD & Linux offer SETRESUID; Solaris does not;
SOLARIS: through /proc FS any process can examine its 3 UIDs and a
superuser process can set any of those UIDs;
SETEUID(newEUID):
--sets EUID; doesn't touch RUID or SUID
--Among UNIX systems, if the current EUID != ROOT
(a) Solaris, Linux
newEUID can equal EUID, RUID, or SUID
(b) FreeBSD
newEUID can equal RUID or SUID
SETREUID(newRUID,newEUID)
--modifies RUID and EUID and in some cases SUID
(a) Solaris & Linux: a process can swap RUID & EUID
(b) FreeBSD: a process can't switch RUID & EUID
SETUID(newUID): POSIX
(a) Linux & Solaris: newUID must equal RUID or SUID (if EUID != 0)
(b) FreeBSD: newUID may equal EUID, too
The action of SETUID depends on whether th process is privileged or not
(a) Linux & Solaris:
if (EUID == 0)
setuid(newID) sets RUID = newUID;
EUID = newUID;
SUID = newUID;
else
setuid(newUID) sets EUID = newUID;
(b) FreeBSD:
setuid(newID) sets RUID = EUID = SUID = newID regardless of whether
current EUID is 0 or not
SETFSUID(newFSUID)
--FSUID used for access control to the FS
--FSUID == EUID unless FSUID explicitly set
--tries to maintian invariant: FSUID = 0 only if RUID, SUID, OR EUID == 0
--if change EUID, that changed val will be propagated to FSUID
Buggy tho; while every setuid & setreuid sets FSUID to EUID, if call
setresuid and *don't change* EUID, then setresuid will NOT set FSUID = EUID
E.g. RUID = EUID = SUID = 0; FSUID = 0;
setresuid(x,x,-1) RUID = EUID = FSUID = x; SUID = 0;
setfsuid(0) RUID = EUID = x; SUID = FSUID = 0;
setresuid(-1,-1,x) RUID = EUID = SUID = x; FSUID = 0;
--> INVARIANT violated
(passing -1 as value means don't change this UID)
SETGID & relatives:
permissions check for setregid != permissions check for setreuid
(in Solaris)
Privileges carried by EUID... so having EGID == 0 doesn't buy you anything
Advertisement
December 24, 2010 at 7:21 am |
i want a function for calculating the number of page faults using euid in linux
December 24, 2010 at 9:49 am |
If I understand you correctly, you are looking for kernel-tracing functionality!? Did you check for FTrace feature, available since vanilla Linux-Kernel 2.6.27?
http://lwn.net/Articles/365835/