When setuid root no longer means setuid root (Forced Privileges)

Starting with Solaris 10 (though similar functionality had been available for more than 15 years in Trusted Solaris variants) it was no longer necessary to be "root" to perform privileged operations via the Solaris kernel.  Instead individual fine grained privileges are checked by the kernel (and in some cases the X server as well).  A number of core setuid root binaries on Solaris were updated to drop all privileges they knew they wouldn't need, but they were still setuid root and thus ran as root for a very short period of time, others that weren't explicitly modified continued to run as root for their lifetime.

The setuid bit on a file system binary (or script) has traditionally indicated to the Solaris kernel that on exec(2) the uid of the process should be switched to that of the owner.  The most common use of this is to make programs run with "root" privileges. 

Trusted Solaris 8 and older had the concept of forced privileges on binaries.  This was achieved by storing with the binary the list of privileges it should always be run with, this required a modified version of the UFS file system and as a result customised backup tools as well (the pax/tar/cpio/ufsdump provided with Solaris knew about these (and other) UFS extensions but not all 3rd party backup software did.  This functionality wasn't carried forward into Solaris 10, which in addition to UFS also has ZFS (which is now the default and only choice for the root file system in Solaris 11 Express).

Solaris 11 Express includes a new implementation of the forced privileges mechanism.  Unlike the version from Trusted Solaris 8 and earlier it is file system agnostic and doesn't store additional information on disk with the binary.

When the kernel is processing an exec(2) it now treats setuid to root differently (setuid to any other uid or setgid is as in Solaris 10).  The kernel now looks for an entry in the Forced Privilege RBAC profile in exec_attr(4) to determine which privileges the program should run with. Instead of having it start with uid root and all privileges, which was the previous behaviour, it will now run with the current uid and just those additional privileges the Forced Privilege RBAC execution profile assigned to that pathname.

We can easily see this difference in behaviour by showing how this works for /usr/sbin/ping.

First lets look with truss at what it looked like prior to the introduction of Forced Privilege:

#  truss -f -texec -p 20549   
3735:    execve("/usr/sbin/ping", 0xFED50640, 0x080477EC)  argc = 2
3735:        \*\*\* SUID: ruid/euid/suid = 101 / 0 / 0  \*\*\*

As we can see the real uid is 101, the effective and saved are 0 (root).  Now lets compare that to the new behaviour:

# truss -f -texec -p 20549
3590:    execve("/usr/sbin/ping", 0xFED50638, 0x080477EC)  argc = 2
3590:        \*\*\* FPRIV: P/E: net_icmpaccess,sys_ip_config \*\*\*

This time the ruid/euid/suid doesn't change (all three stay at 101 in this example) instead we set the permitted (P) and effective (E) privilege sets to be the set obtained for /usr/sbin/ping in the "Forced Privileges" RBAC profile (net_icmpaccess,sys_ip_config in this case).

This means that at no time was ping running with uid 0 nor did it ever have all privileges, so we no longer require the code for ping to do its own privilege management.

If there is't an entry in the "Forced Privileges" RBAC profile for the program being exec'd then the traditional behaviour of setting euid to 0 remains.

As a result Solaris 11 Express currently has 15 fewer "true" setuid binaries - note that the list of binaries in the "Forced Privileges" RBAC profile may change over time including in software updates.

So setuid root no longer means setuid root in all cases.


I think the obvious question is that can the default behavior be changed so that if there isn't an entry in the "Forced Privileges" RBAC profile, the program isn't exec'd and an syslog alert generated?

Posted by Steven Fenger on January 04, 2011 at 06:51 AM GMT #

Unlikely we would change that to be the default behaviour of Solaris because that would break 3rd party software that requires setuid root binaries, it would also break Solaris 11 Express as currently delivered as we aren't yet at the stage where we have entries in the Forced Privileges profile for all of the setuid programs.

Use of the nosetuid mount option obviously doesn't protect the root filesystem (since you can't do that!). If we did providing logging for this it is more likely we would use a Solaris Audit record to do so (note this is not a commitment to provide any logging)

Posted by Darren Moffat on January 04, 2011 at 08:05 AM GMT #

while working with newer AIX, i came to appreciate the use of pvi which is a nice way to enable users to edit configuration file that would normally need additional privileges.
will something like that ever be implemented in solaris?
also, will it ever be possible to configure pfexec to ask for a password when trying to run priviliged commands a-la-sudo?

Posted by nacho on January 04, 2011 at 10:34 AM GMT #

I think that Steven is asking if one can configure S11 in such a way so if there is no special entry in exec_attr for a setuid=0 binary it will be denied to be executed or at last it would be executed as a user which called it. Plus the fact will be logged via syslog. I don't think he is asking to make it the default behaviour out-of-the-box rather if it is possible to configure it in such way.

Posted by Robert Milkowski on January 04, 2011 at 04:23 PM GMT #

Yes, I would want a settable default behavior. That way you could lock down a production machine and be notified if a new or unknown setuid executable was introduced to the machine.

Posted by Steven Fenger on January 06, 2011 at 07:38 AM GMT #

Hi nacho, pvi sounds a lot like the old adminvi command from the Trusted versions of SunOS 4.1.x and a lot like the trusted_editor command we had in Trusted Solaris 8. There isn't currently an equivalent of that in Solaris 11 Express.

For pfexec prompting for a password they way sudo does, it has been considered but pfexec is not implemented "in kernel" so it isn't possible to do it like sudo does. However there are plans to provide the ability to allow roles to authenticate with the users password rather than the role password - that would allow using 'su -c' a bit like sudo.

Posted by Darren Moffat on January 07, 2011 at 04:03 AM GMT #

Post a Comment:
  • HTML Syntax: NOT allowed

Darren Moffat-Oracle


« July 2016