The code in opennsd-compat/port-solaris.c should not change PRIV_LIMIT when PRIV_XPOLICY is set. In Solaris, it is possible for a user to have an extended policy in place; the LIMIT set restricts the extended policy and so should not be restricted.
This issue will immediately be addressed in Solaris 11 by Oracle via a patch. This patch is being offered for inclusion upstream: diff -ur orig/openbsd-compat/port-solaris.c new/openbsd-compat/port-solaris.c --- orig/openbsd-compat/port-solaris.c Tue Feb 6 08:22:44 2018 +++ new/openbsd-compat/port-solaris.c Tue Feb 6 08:45:21 2018 @@ -306,6 +306,31 @@ priv_delset(npset, PRIV_PROC_SESSION) != 0) fatal("priv_delset: %s", strerror(errno)); +#ifdef PRIV_XPOLICY + /* + * It is possible that the user has an extended policy + * in place; the LIMIT set restricts the extended policy + * and so should not be restricted. + * PRIV_XPOLICY is newly defined in Solaris 11 though the extended + * policy was not implemented until Solaris 11.1. + */ + if (getpflags(PRIV_XPOLICY) == 1) { + if (getppriv(PRIV_LIMIT, pset) != 0) + fatal("getppriv: %s", strerror(errno)); + + priv_intersect(pset, npset); + + if (setppriv(PRIV_SET, PRIV_LIMIT, npset) != 0) + fatal("setppriv: %s", strerror(errno)); + } else +#endif + { + /* Cannot exec, so we can kill the limit set. */ + priv_emptyset(pset); + if (setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0) + fatal("setppriv: %s", strerror(errno)); + } + if (getppriv(PRIV_PERMITTED, pset) != 0) fatal("getppriv: %s", strerror(errno)); @@ -312,7 +337,6 @@ priv_intersect(pset, npset); if (setppriv(PRIV_SET, PRIV_PERMITTED, npset) != 0 || - setppriv(PRIV_SET, PRIV_LIMIT, npset) != 0 || setppriv(PRIV_SET, PRIV_INHERITABLE, npset) != 0) fatal("setppriv: %s", strerror(errno));
Could you point us to some documentation on PRIV_XPOLICY? I can't see anything in any of the available online manual pages and I'd like to understand what is wrong rather than blindly commit this.
Remove release target until we understand this properly.
(In reply to Damien Miller from comment #2) > Could you point us to some documentation on PRIV_XPOLICY? I can't > see anything in any of the available online manual pages and I'd > like to understand what is wrong rather than blindly commit this. Sorry for the delay! Please see: Securing Users and Processes in Oracle, Solaris 11.3's Locking Down Resources by Using Extended Privileges: https://docs.oracle.com/cd/E53394_01/html/E54830/rbactask-lockdown-1.html Solaris 11.3 ppriv man page, especially examples 6 & 7: https://docs.oracle.com/cd/E86824_01/html/E54763/ppriv-1.html Please let me know if you need further info. Thx!
I'm still a little unclear, sorry: It looks like the !PRIV_XPOLICY case gets a more restricted (empty) PRIV_LIMIT set than the case where an PRIV_XPOLICY exists. Why can't an empty set be used in both cases?
The end-goal is to set effective privileges for the current process (and, to be safe, for any children) but changes to PRIV_LIMIT are not put into effect until an exec(); refer to "man setppriv" referenced above: Changing PRIV_LIMIT does nothing to the current process, only to its children. The other thing to note from that man page is that when privileges are removed from PRIV_PERMITTED, they are ALSO immediately and silently removed from PRIV_EFFECTIVE: if npset is more restrictive than PRIV_PERMITTED, the first call to setppriv() removes privileges from both PRIV_PERMITTED and PRIV_EFFECTIVE, which has the desired effect of removing privileges from the current process. If npset is more restrictive that PRIV_INHERITABLE, the second call to setppriv() removes permissions from that set, covering any subsequent processes created with exec(). Since the privileges of the current process were limited to PRIV_INHERITABLE when it was exec()'d, if npset is more restrictive than PRIV_INHERITABLE it is likely more restrictive than PRIV_PERMITTED - but the reverse might not be true in general, since PRIV_PERMITTED might have already been reduced to less than PRIV_INHERITABLE. The end result of these two calls is that PRIV_INHERITABLE and PRIV_PERMITTED match npset, controlling both the privileges available to the current process and the privileges available to any children. Modifying PRIV_LIMIT is redundant and unnecessary. I don't know that it is harmful (would we ever want to query it?) but it is unneeded. Refer also to https://docs.oracle.com/cd/E86824_01/html/E54776/privileges-5.html