I read from some books that the seteuid together with euid and saved UID can be used to drop root privilege temporarily. The case is:
- set euid to a non-root one.
- do something which does not require root privilege.
- set euid to root again (this works because root is still the saved UID).
I think this is flawed. During step 2, some malicious code could also invoke seteuid to root so this method of dropping root privilege doesn't prevent hijacking code from gain root privilege. Is my analysis correct? If so, what could seteuid-on-saved-UID be used for?
Your concern that the malicious code might also restore the effective UID to the saved UID is legitimate. If you are concerned about this, maybe you should not be using a setuid root program in the first place. (LD_PRELOAD and other such things are worrisome in general; they are also restricted when a program is running with setuid privileges.)
Often, though, the mechanism is used in a forked child, where the child will execute some other process without the elevated privileges because the saved UID won't be retained by the executed process. If the malicious code manages to take over before the exec()
, then you still have problems. After the exec()
, the malicious code only has the privileges of the real UID, and the user could have done whatever it is that the malicious code did.
Setuid is flawed in general, because of the possibility of privilege escalation without authentication. Even the notion of root privilege is getting a bit antiquated. Most platforms have updated methods for gaining additional privileges, whether it be from shell with "sudo" on unix and "pfexec" on Solaris, for example.
Additionally they generally have more fine grained controls on which privileges they need escalated. With setuid, its all or none, but with RBAC on Solaris for example, the framework provides methods for specifying which exact privilege(s) you need, generally lower level stuff like opening files, reading directories, etc..
In general, I think now days you should avoid setuid for anything and use newer APIs instead.