int applyOCIcapabilities(struct jail_capset ocicapset, uint64_t retain)
{
struct __user_cap_header_struct uh = {};
- struct __user_cap_data_struct ud;
+ struct __user_cap_data_struct ud[2];
int cap;
int is_set;
uh.version = _LINUX_CAPABILITY_VERSION_3;
uh.pid = getpid();
- if (capget(&uh, &ud)) {
+ if (capget(&uh, ud)) {
ERROR("capget() failed\n");
return -1;
}
- DEBUG("old capabilities: Pe=%08x Pp=%08x Pi=%08x\n", ud.effective, ud.permitted, ud.inheritable);
+ DEBUG("old capabilities: Pe=%016llx Pp=%016llx Pi=%016llx\n",
+ 0LLU | ud[0].effective | (0LLU | ud[1].effective) << 32,
+ 0LLU | ud[0].permitted | (0LLU | ud[1].permitted) << 32,
+ 0LLU | ud[0].inheritable | (0LLU | ud[1].inheritable) << 32);
- if (ocicapset.effective != JAIL_CAP_ALL)
- ud.effective = ocicapset.effective | retain;
+ if (ocicapset.effective != JAIL_CAP_ALL) {
+ ud[0].effective = (ocicapset.effective | retain) & 0xFFFFFFFFU;
+ ud[1].effective = ((ocicapset.effective | retain) >> 32) & 0xFFFFFFFFU;
+ }
- if (ocicapset.permitted != JAIL_CAP_ALL)
- ud.permitted = ocicapset.permitted | retain;
+ if (ocicapset.permitted != JAIL_CAP_ALL) {
+ ud[0].permitted = (ocicapset.permitted | retain) & 0xFFFFFFFFU;
+ ud[1].permitted = ((ocicapset.permitted | retain) >> 32) & 0xFFFFFFFFU;
+ }
- if (ocicapset.inheritable != JAIL_CAP_ALL)
- ud.inheritable = ocicapset.inheritable;
+ if (ocicapset.inheritable != JAIL_CAP_ALL) {
+ ud[0].inheritable = (ocicapset.inheritable | retain) & 0xFFFFFFFFU;
+ ud[1].inheritable = ((ocicapset.inheritable | retain) >> 32) & 0xFFFFFFFFU;
+ }
- DEBUG("new capabilities: Pe=%08x Pp=%08x Pi=%08x\n", ud.effective, ud.permitted, ud.inheritable);
+ DEBUG("new capabilities: Pe=%016llx Pp=%016llx Pi=%016llx\n",
+ 0LLU | ud[0].effective | (0LLU | ud[1].effective) << 32,
+ 0LLU | ud[0].permitted | (0LLU | ud[1].permitted) << 32,
+ 0LLU | ud[0].inheritable | (0LLU | ud[1].inheritable) << 32);
- if (capset(&uh, &ud)) {
+ if (capset(&uh, ud)) {
ERROR("capset() failed\n");
return -1;
}
{
int pw_uid, pw_gid, gr_gid;
- if (prctl(PR_SET_SECUREBITS, SECBIT_NO_SETUID_FIXUP)) {
- ERROR("prctl(PR_SET_SECUREBITS) failed: %m\n");
- exit(EXIT_FAILURE);
+ /*
+ * make sure setuid/setgid won't drop capabilities in case capabilities
+ * have been specified explicitely.
+ */
+ if (opts.capset.apply) {
+ if (prctl(PR_SET_SECUREBITS, SECBIT_NO_SETUID_FIXUP)) {
+ ERROR("prctl(PR_SET_SECUREBITS) failed: %m\n");
+ exit(EXIT_FAILURE);
+ }
}
/* drop capabilities, retain those still needed to further setup jail */
if (opts.set_umask)
umask(opts.umask);
- if (prctl(PR_SET_SECUREBITS, 0)) {
- ERROR("prctl(PR_SET_SECUREBITS) failed: %m\n");
- exit(EXIT_FAILURE);
+ /* restore securebits back to normal */
+ if (opts.capset.apply) {
+ if (prctl(PR_SET_SECUREBITS, 0)) {
+ ERROR("prctl(PR_SET_SECUREBITS) failed: %m\n");
+ exit(EXIT_FAILURE);
+ }
}
/* drop remaining capabilities to end up with specified sets */