On Tue, 3 Feb 2015, Casey Schaufler wrote:

> > (I wasn't going to ask bc I assumed not, but heck maybe you're bored
> > on a desert island or snowed in and just looking for an excuse to hack :)
>
> Not at all bored, but I think this could be important.

Ok here is a draft of a patch that follows these ideas.

It also adds an ambient field and sets the field if a new capability

        CAP_AMBIENT_MASK

is set. The perm calcualtion is as suggested by Serge.


If CAP_AMBIENT_MASK is set the inheritable caps become the ambient ones.

If it is not set then the ambient caps are copied from the parent.


DRAFT --- not a working patch:

Index: linux/include/linux/capability.h
===================================================================
--- linux.orig/include/linux/capability.h       2015-02-03 13:25:03.000000000 
-0600
+++ linux/include/linux/capability.h    2015-02-03 13:39:23.385424676 -0600
@@ -29,6 +29,7 @@ struct cpu_vfs_cap_data {
        __u32 magic_etc;
        kernel_cap_t permitted;
        kernel_cap_t inheritable;
+       kernel_cap_t ambient;
 };

 #define _USER_CAP_HEADER_SIZE  (sizeof(struct __user_cap_header_struct))
Index: linux/include/uapi/linux/capability.h
===================================================================
--- linux.orig/include/uapi/linux/capability.h  2014-07-10 16:10:29.814424392 
-0500
+++ linux/include/uapi/linux/capability.h       2015-02-03 13:26:13.231081452 
-0600
@@ -351,8 +351,10 @@ struct vfs_cap_data {

 #define CAP_AUDIT_READ         37

+/* Set the current inheritable mask as the ambient inheritable mask */
+#define CAP_AMBIENT_MASK       38

-#define CAP_LAST_CAP         CAP_AUDIT_READ
+#define CAP_LAST_CAP         CAP_AMBIENT_MASK

 #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)

Index: linux/security/commoncap.c
===================================================================
--- linux.orig/security/commoncap.c     2015-02-03 13:25:03.000000000 -0600
+++ linux/security/commoncap.c  2015-02-03 13:43:16.317859741 -0600
@@ -349,17 +349,24 @@ static inline int bprm_caps_from_vfs_cap
        CAP_FOR_EACH_U32(i) {
                __u32 permitted = caps->permitted.cap[i];
                __u32 inheritable = caps->inheritable.cap[i];
+               __u32 ambient = caps->ambient.cap[i];

                /*
                 * pP' = (X & fP) | (pI & fI)
                 */
                new->cap_permitted.cap[i] =
                        (new->cap_bset.cap[i] & permitted) |
-                       (new->cap_inheritable.cap[i] & inheritable);
+                       (new->cap_inheritable.cap[i] & inheritable) |
+                       (ambient & inheritable);

                if (permitted & ~new->cap_permitted.cap[i])
                        /* insufficient to execute correctly */
                        ret = -EPERM;
+
+               if (capable(CAP_AMBIENT_MASK))
+                       new->cap_ambient.cap[i] = inheritable;
+               else
+                       new->cap_ambient.cap[i] = ambient;
        }

        /*
Index: linux/include/linux/cred.h
===================================================================
--- linux.orig/include/linux/cred.h     2014-12-18 11:17:49.731948737 -0600
+++ linux/include/linux/cred.h  2015-02-03 13:37:32.701019201 -0600
@@ -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 inherited caps */
 #ifdef CONFIG_KEYS
        unsigned char   jit_keyring;    /* default keyring to attach requested
                                         * keys to */


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to