libcap-ng/libcap-ng-0.8.2-apply.patch

106 lines
2.8 KiB
Diff

diff -urp libcap-ng-0.8.2.orig/src/cap-ng.c libcap-ng-0.8.2/src/cap-ng.c
--- libcap-ng-0.8.2.orig/src/cap-ng.c 2020-11-20 13:37:57.000000000 -0500
+++ libcap-ng-0.8.2/src/cap-ng.c 2020-11-20 13:57:54.934059250 -0500
@@ -680,6 +680,8 @@ int capng_updatev(capng_act_t action, ca
int capng_apply(capng_select_t set)
{
+ int rc = 0;
+
// Before updating, we expect that the data is initialized to something
if (m.state < CAPNG_INIT)
return -1;
@@ -695,52 +697,78 @@ int capng_apply(capng_select_t set)
for (i=0; i <= last_cap; i++) {
if (capng_have_capability(CAPNG_BOUNDING_SET,
i) == 0) {
- if (prctl(PR_CAPBSET_DROP, i, 0, 0, 0) <0)
- return -2;
+ if (prctl(PR_CAPBSET_DROP, i, 0, 0, 0) <0) {
+ rc = -2;
+ goto try_caps;
+ }
}
}
m.state = CAPNG_APPLIED;
- if (get_bounding_set() < 0)
- return -3;
+ if (get_bounding_set() < 0) {
+ rc = -3;
+ goto try_caps;
+ }
} else {
memcpy(&m, &state, sizeof(m)); /* restore state */
- return -4;
+ rc = -4;
+ goto try_caps;
}
#endif
}
+
+ // Try caps is here so that if someone had SELECT_BOTH and we blew up
+ // doing the bounding set, we at least try to set any capabilities
+ // before returning in case the caller also doesn't bother checking
+ // the return code.
+try_caps:
if (set & CAPNG_SELECT_CAPS) {
if (capset((cap_user_header_t)&m.hdr,
(cap_user_data_t)&m.data) == 0)
m.state = CAPNG_APPLIED;
else
- return -5;
+ rc = -5;
}
- // Put ambient last so that inheritable and permitted are set
+
+ // Most programs do not and should not mess with ambient capabilities.
+ // Instead of returning here if rc is set, we'll let it try to
+ // do something with ambient capabilities in hopes that it's lowering
+ // capabilities. Again, this is for people that don't check their
+ // return codes.
+ //
+ // Do ambient last so that inheritable and permitted are set by the
+ // time we get here.
if (set & CAPNG_SELECT_AMBIENT) {
#ifdef PR_CAP_AMBIENT
if (capng_have_capabilities(CAPNG_SELECT_AMBIENT) ==
CAPNG_NONE) {
if (prctl(PR_CAP_AMBIENT,
- PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0) < 0)
- return -6;
+ PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0) < 0) {
+ rc = -6;
+ goto out;
+ }
} else {
unsigned int i;
// Clear them all
if (prctl(PR_CAP_AMBIENT,
- PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0) < 0)
- return -7;
+ PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0) < 0) {
+ rc = -7;
+ goto out;
+ }
for (i=0; i <= last_cap; i++) {
if (capng_have_capability(CAPNG_AMBIENT, i))
if (prctl(PR_CAP_AMBIENT,
- PR_CAP_AMBIENT_RAISE, i, 0, 0) < 0)
- return -8;
+ PR_CAP_AMBIENT_RAISE, i, 0, 0) < 0){
+ rc = -8;
+ goto out;
+ }
}
}
m.state = CAPNG_APPLIED;
#endif
}
- return 0;
+out:
+ return rc;
}
#ifdef VFS_CAP_U32