Skip dropping the bounding set without SECURE_NOROOT.

If we're asked to skip setting *and* locking the SECURE_NOROOT
securebit, also skip dropping the bounding set. If the caller wants to
regain all capabilities when executing a set-user-ID-root program,
allow them to do so. The default behavior (i.e. the behavior without
|securebits_skip_mask| set) will still put the jailed process tree in a
capabilities-only environment.

This will allow giving powerd on Chrome OS some capabilities without
breaking other things.

Bug: 78629772
Test: New unit tests.
Test: Ad-hoc with fork+exec program + setuid program + -B 0x3
Test: Setuid program is able to keep all caps.

Change-Id: I36f79a42666720a65d88ec48454b56695f25b64b
diff --git a/system.c b/system.c
index ad69717..5e2a6f6 100644
--- a/system.c
+++ b/system.c
@@ -43,6 +43,12 @@
 _Static_assert(SECURE_ALL_BITS == 0x55, "SECURE_ALL_BITS == 0x55.");
 #endif
 
+int secure_noroot_set_and_locked(uint64_t mask)
+{
+	return (mask & (SECBIT_NOROOT | SECBIT_NOROOT_LOCKED)) ==
+	       (SECBIT_NOROOT | SECBIT_NOROOT_LOCKED);
+}
+
 int lock_securebits(uint64_t skip_mask)
 {
 	/*
@@ -54,6 +60,7 @@
 	unsigned long securebits =
 	    (SECURE_BITS_NO_AMBIENT | SECURE_LOCKS_NO_AMBIENT) & ~skip_mask;
 	if (!securebits) {
+		warn("not locking any securebits");
 		return 0;
 	}
 	int securebits_ret = prctl(PR_SET_SECUREBITS, securebits);