]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
lsm: add lsmprop_to_secctx hook
authorCasey Schaufler <casey@schaufler-ca.com>
Wed, 9 Oct 2024 17:32:11 +0000 (10:32 -0700)
committerPaul Moore <paul@paul-moore.com>
Fri, 11 Oct 2024 18:34:12 +0000 (14:34 -0400)
Add a new hook security_lsmprop_to_secctx() and its LSM specific
implementations. The LSM specific code will use the lsm_prop element
allocated for that module. This allows for the possibility that more
than one module may be called upon to translate a secid to a string,
as can occur in the audit code.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
[PM: subject line tweak]
Signed-off-by: Paul Moore <paul@paul-moore.com>
include/linux/lsm_hook_defs.h
include/linux/security.h
security/apparmor/include/secid.h
security/apparmor/lsm.c
security/apparmor/secid.c
security/security.c
security/selinux/hooks.c
security/selinux/include/audit.h
security/smack/smack_lsm.c

index ea7f17e3775610815ba58606a34edf8438e073fc..ed6ea0b1ec574979f2f05a19eeb3baaa2218e900 100644 (file)
@@ -294,6 +294,8 @@ LSM_HOOK(int, -EINVAL, setprocattr, const char *name, void *value, size_t size)
 LSM_HOOK(int, 0, ismaclabel, const char *name)
 LSM_HOOK(int, -EOPNOTSUPP, secid_to_secctx, u32 secid, char **secdata,
         u32 *seclen)
+LSM_HOOK(int, -EOPNOTSUPP, lsmprop_to_secctx, struct lsm_prop *prop,
+        char **secdata, u32 *seclen)
 LSM_HOOK(int, 0, secctx_to_secid, const char *secdata, u32 seclen, u32 *secid)
 LSM_HOOK(void, LSM_RET_VOID, release_secctx, char *secdata, u32 seclen)
 LSM_HOOK(void, LSM_RET_VOID, inode_invalidate_secctx, struct inode *inode)
index a4f020491e7cdea8bfcda7261707e3d0eee0e583..f1c68e38b15d8970992b31cd66555e7b2418bea6 100644 (file)
@@ -535,6 +535,7 @@ int security_setprocattr(int lsmid, const char *name, void *value, size_t size);
 int security_netlink_send(struct sock *sk, struct sk_buff *skb);
 int security_ismaclabel(const char *name);
 int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
+int security_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata, u32 *seclen);
 int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
 void security_release_secctx(char *secdata, u32 seclen);
 void security_inode_invalidate_secctx(struct inode *inode);
@@ -1488,7 +1489,14 @@ static inline int security_ismaclabel(const char *name)
        return 0;
 }
 
-static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+static inline int security_secid_to_secctx(u32 secid, char **secdata,
+                                          u32 *seclen)
+{
+       return -EOPNOTSUPP;
+}
+
+static inline int security_lsmprop_to_secctx(struct lsm_prop *prop,
+                                            char **secdata, u32 *seclen)
 {
        return -EOPNOTSUPP;
 }
index a912a5d5d04f5ea89980ab0174c3615ab657b992..cc6d1c9f4a472c4ec1ab23593756d3e7ee44ec6b 100644 (file)
@@ -26,6 +26,8 @@ extern int apparmor_display_secid_mode;
 
 struct aa_label *aa_secid_to_label(u32 secid);
 int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
+int apparmor_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata,
+                              u32 *seclen);
 int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
 void apparmor_release_secctx(char *secdata, u32 seclen);
 
index f5d05297d59ee4b0a563f11cb7b0bdf38ea4f4cd..a58b72ed246cac7f6551de4e07c7aad7d42f2be6 100644 (file)
@@ -1517,6 +1517,7 @@ static struct security_hook_list apparmor_hooks[] __ro_after_init = {
 #endif
 
        LSM_HOOK_INIT(secid_to_secctx, apparmor_secid_to_secctx),
+       LSM_HOOK_INIT(lsmprop_to_secctx, apparmor_lsmprop_to_secctx),
        LSM_HOOK_INIT(secctx_to_secid, apparmor_secctx_to_secid),
        LSM_HOOK_INIT(release_secctx, apparmor_release_secctx),
 
index 83d3d1e6d9dcb9d08e027ccac3ad2d2ae37e9229..34610888559f9718c2dbdf1db02d3df64995a9f8 100644 (file)
@@ -61,10 +61,10 @@ struct aa_label *aa_secid_to_label(u32 secid)
        return xa_load(&aa_secids, secid);
 }
 
-int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+static int apparmor_label_to_secctx(struct aa_label *label, char **secdata,
+                                   u32 *seclen)
 {
        /* TODO: cache secctx and ref count so we don't have to recreate */
-       struct aa_label *label = aa_secid_to_label(secid);
        int flags = FLAG_VIEW_SUBNS | FLAG_HIDDEN_UNCONFINED | FLAG_ABS_ROOT;
        int len;
 
@@ -90,6 +90,27 @@ int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
        return 0;
 }
 
+int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+{
+       struct aa_label *label = aa_secid_to_label(secid);
+
+       return apparmor_label_to_secctx(label, secdata, seclen);
+}
+
+int apparmor_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata,
+                              u32 *seclen)
+{
+       struct aa_label *label;
+
+       /* scaffolding */
+       if (!prop->apparmor.label && prop->scaffold.secid)
+               label = aa_secid_to_label(prop->scaffold.secid);
+       else
+               label = prop->apparmor.label;
+
+       return apparmor_label_to_secctx(label, secdata, seclen);
+}
+
 int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
 {
        struct aa_label *label;
index deab7f912e12d4f545702c3530d69bd25d16ec72..1842f1325e774dfe7bf02f60a0f0bdedce543c4e 100644 (file)
@@ -4311,6 +4311,27 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
 }
 EXPORT_SYMBOL(security_secid_to_secctx);
 
+/**
+ * security_lsmprop_to_secctx() - Convert a lsm_prop to a secctx
+ * @prop: lsm specific information
+ * @secdata: secctx
+ * @seclen: secctx length
+ *
+ * Convert a @prop entry to security context.  If @secdata is NULL the
+ * length of the result will be returned in @seclen, but no @secdata
+ * will be returned.  This does mean that the length could change between
+ * calls to check the length and the next call which actually allocates
+ * and returns the @secdata.
+ *
+ * Return: Return 0 on success, error on failure.
+ */
+int security_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata,
+                              u32 *seclen)
+{
+       return call_int_hook(lsmprop_to_secctx, prop, secdata, seclen);
+}
+EXPORT_SYMBOL(security_lsmprop_to_secctx);
+
 /**
  * security_secctx_to_secid() - Convert a secctx to a secid
  * @secdata: secctx
index fc926d3cac6e25e9411f918eb341c35a52504999..6e88faf3c6e566beb59c05effac309f3fcb3be46 100644 (file)
@@ -6601,8 +6601,19 @@ static int selinux_ismaclabel(const char *name)
 
 static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
 {
-       return security_sid_to_context(secid,
-                                      secdata, seclen);
+       return security_sid_to_context(secid, secdata, seclen);
+}
+
+static int selinux_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata,
+                                    u32 *seclen)
+{
+       u32 secid = prop->selinux.secid;
+
+       /* scaffolding */
+       if (!secid)
+               secid = prop->scaffold.secid;
+
+       return selinux_secid_to_secctx(secid, secdata, seclen);
 }
 
 static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
@@ -7347,6 +7358,7 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
        LSM_HOOK_INIT(inode_alloc_security, selinux_inode_alloc_security),
        LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security),
        LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx),
+       LSM_HOOK_INIT(lsmprop_to_secctx, selinux_lsmprop_to_secctx),
        LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx),
        LSM_HOOK_INIT(sk_alloc_security, selinux_sk_alloc_security),
        LSM_HOOK_INIT(tun_dev_alloc_security, selinux_tun_dev_alloc_security),
index c745ea2a993d3549bf013593dee11954a07db120..d5b0425055e4249fbdde0a4fc27d18f55104bcab 100644 (file)
@@ -49,7 +49,8 @@ void selinux_audit_rule_free(void *rule);
  * Returns 1 if the context id matches the rule, 0 if it does not, and
  * -errno on failure.
  */
-int selinux_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op, void *rule);
+int selinux_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op,
+                            void *rule);
 
 /**
  * selinux_audit_rule_known - check to see if rule contains selinux fields.
index 535233ad720361a9d39c428cfe4b87f3056be4e9..66da7cbcc0b72dd8fbb10cbefc69f333a55a74ec 100644 (file)
@@ -4768,7 +4768,7 @@ static int smack_audit_rule_known(struct audit_krule *krule)
 static int smack_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op,
                                  void *vrule)
 {
-       struct smack_known *skp;
+       struct smack_known *skp = prop->smack.skp;
        char *rule = vrule;
 
        if (unlikely(!rule)) {
@@ -4780,10 +4780,8 @@ static int smack_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op,
                return 0;
 
        /* scaffolding */
-       if (!prop->smack.skp && prop->scaffold.secid)
+       if (!skp && prop->scaffold.secid)
                skp = smack_from_secid(prop->scaffold.secid);
-       else
-               skp = prop->smack.skp;
 
        /*
         * No need to do string comparisons. If a match occurs,
@@ -4814,7 +4812,6 @@ static int smack_ismaclabel(const char *name)
        return (strcmp(name, XATTR_SMACK_SUFFIX) == 0);
 }
 
-
 /**
  * smack_secid_to_secctx - return the smack label for a secid
  * @secid: incoming integer
@@ -4833,6 +4830,29 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
        return 0;
 }
 
+/**
+ * smack_lsmprop_to_secctx - return the smack label
+ * @prop: includes incoming Smack data
+ * @secdata: destination
+ * @seclen: how long it is
+ *
+ * Exists for audit code.
+ */
+static int smack_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata,
+                                  u32 *seclen)
+{
+       struct smack_known *skp = prop->smack.skp;
+
+       /* scaffolding */
+       if (!skp && prop->scaffold.secid)
+               skp = smack_from_secid(prop->scaffold.secid);
+
+       if (secdata)
+               *secdata = skp->smk_known;
+       *seclen = strlen(skp->smk_known);
+       return 0;
+}
+
 /**
  * smack_secctx_to_secid - return the secid for a smack label
  * @secdata: smack label
@@ -5192,6 +5212,7 @@ static struct security_hook_list smack_hooks[] __ro_after_init = {
 
        LSM_HOOK_INIT(ismaclabel, smack_ismaclabel),
        LSM_HOOK_INIT(secid_to_secctx, smack_secid_to_secctx),
+       LSM_HOOK_INIT(lsmprop_to_secctx, smack_lsmprop_to_secctx),
        LSM_HOOK_INIT(secctx_to_secid, smack_secctx_to_secid),
        LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx),
        LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx),