Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S966480AbbBDWCk (ORCPT ); Wed, 4 Feb 2015 17:02:40 -0500 Received: from resqmta-ch2-06v.sys.comcast.net ([69.252.207.38]:37325 "EHLO resqmta-ch2-06v.sys.comcast.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933647AbbBDWCh (ORCPT ); Wed, 4 Feb 2015 17:02:37 -0500 Date: Wed, 4 Feb 2015 16:02:35 -0600 (CST) From: Christoph Lameter X-X-Sender: cl@gentwo.org To: Andy Lutomirski cc: "Serge E. Hallyn" , "Andrew G. Morgan" , Serge Hallyn , Serge Hallyn , Jonathan Corbet , Aaron Jones , "Ted Ts'o" , LSM List , lkml , Andrew Morton Subject: Re: [RFC] Implement ambient capability set V2 In-Reply-To: Message-ID: References: <20150204211617.GA20787@mail.hallyn.com> Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3814 Lines: 120 Subject: [capabilities] Implement ambient capability set V2 DRAFT -- untested -- DRAFT Implement an ambient capabilty set to allow capabilties to be inherited with unix semantics used also for other attributes. Implements PR_CAP_AMBIENT. The second argument to prctl is a the capability number and the third the desired state. 0 for off. Otherwise on. Serge: A new capability set, pA, is empty by default. You can add bits to it using prctl if ns_capable(CAP_SETPCAP) and all the new bits are in your pE. Once set, they stay until they are removed using prctl. At exec, pA' = pA, and fI |= pA (after reading fI from disk but before calculating pI'). Since the ambient caps "stay on" cap_inheritable does not really matter anymore. Simply set the permitted caps when the ambient cap is set. Signed-off-by: Christoph Lameter Index: linux/security/commoncap.c =================================================================== --- linux.orig/security/commoncap.c +++ linux/security/commoncap.c @@ -351,9 +351,10 @@ static inline int bprm_caps_from_vfs_cap __u32 inheritable = caps->inheritable.cap[i]; /* - * pP' = (X & fP) | (pI & fI) + * pP' = (pA & fP) | (X & fP) | (pI & fI) */ new->cap_permitted.cap[i] = + (current_cred()->cap_ambient.cap[i] & permitted) | (new->cap_bset.cap[i] & permitted) | (new->cap_inheritable.cap[i] & inheritable); @@ -453,9 +454,13 @@ static int get_file_caps(struct linux_bi if (rc == -EINVAL) printk(KERN_NOTICE "%s: get_vfs_caps_from_disk returned %d for %s\n", __func__, rc, bprm->filename); - else if (rc == -ENODATA) - rc = 0; - goto out; + else if (rc != -ENODATA) + goto out; + rc = 0; + if (cap_isclear(current_cred()->cap_ambient)) + goto out; + *effective = true; + *has_cap = true; } rc = bprm_caps_from_vfs_caps(&vcaps, bprm, effective, has_cap); @@ -577,6 +582,7 @@ skip: } new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS); + new->cap_ambient = old->cap_ambient; return 0; } @@ -933,6 +939,23 @@ int cap_task_prctl(int option, unsigned new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS); return commit_creds(new); + case PR_CAP_AMBIENT: + if (!ns_capable(current_user_ns(), CAP_SETPCAP)) + return -EPERM; + + if (!cap_valid(arg2)) + return -EINVAL; + + if (!ns_capable(current_user_ns(), arg2)) + return -EPERM; + + new = prepare_creds(); + if (arg3 == 0) + cap_lower(new->cap_ambient, arg2); + else + cap_raise(new->cap_ambient, arg2); + return commit_creds(new); + default: /* No functionality available - continue with default */ return -ENOSYS; Index: linux/include/linux/cred.h =================================================================== --- linux.orig/include/linux/cred.h +++ linux/include/linux/cred.h @@ -122,6 +122,7 @@ struct cred { kernel_cap_t cap_permitted; /* caps we're permitted */ kernel_cap_t cap_effective; /* caps we can actually use */ kernel_cap_t cap_bset; /* capability bounding set */ + kernel_cap_t cap_ambient; /* Ambient capability set */ #ifdef CONFIG_KEYS unsigned char jit_keyring; /* default keyring to attach requested * keys to */ Index: linux/include/uapi/linux/prctl.h =================================================================== --- linux.orig/include/uapi/linux/prctl.h +++ linux/include/uapi/linux/prctl.h @@ -185,4 +185,7 @@ struct prctl_mm_map { #define PR_MPX_ENABLE_MANAGEMENT 43 #define PR_MPX_DISABLE_MANAGEMENT 44 +/* Control the ambient capability set */ +#define PR_CAP_AMBIENT 45 + #endif /* _LINUX_PRCTL_H */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/