]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
lsm: security_lsmblob_to_secctx module selection
authorCasey Schaufler <casey@schaufler-ca.com>
Sat, 16 Aug 2025 17:28:57 +0000 (10:28 -0700)
committerPaul Moore <paul@paul-moore.com>
Sat, 30 Aug 2025 14:15:29 +0000 (10:15 -0400)
Add a parameter lsmid to security_lsmblob_to_secctx() to identify which
of the security modules that may be active should provide the security
context. If the value of lsmid is LSM_ID_UNDEF the first LSM providing
a hook is used. security_secid_to_secctx() is unchanged, and will
always report the first LSM providing a hook.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
[PM: subj tweak]
Signed-off-by: Paul Moore <paul@paul-moore.com>
include/linux/security.h
kernel/audit.c
kernel/auditsc.c
net/netlabel/netlabel_user.c
security/security.c

index 521bcb5b97170c7f9b0abd79fc6fe756d4ff29ee..6d1ed6e7387bc512c9d6e1bb709893602805a5ce 100644 (file)
@@ -567,7 +567,8 @@ int security_getprocattr(struct task_struct *p, int lsmid, const char *name,
 int security_setprocattr(int lsmid, const char *name, void *value, size_t size);
 int security_ismaclabel(const char *name);
 int security_secid_to_secctx(u32 secid, struct lsm_context *cp);
-int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp);
+int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp,
+                              int lsmid);
 int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
 void security_release_secctx(struct lsm_context *cp);
 void security_inode_invalidate_secctx(struct inode *inode);
@@ -1551,7 +1552,8 @@ static inline int security_secid_to_secctx(u32 secid, struct lsm_context *cp)
 }
 
 static inline int security_lsmprop_to_secctx(struct lsm_prop *prop,
-                                            struct lsm_context *cp)
+                                            struct lsm_context *cp,
+                                            int lsmid)
 {
        return -EOPNOTSUPP;
 }
index 547967cb4266b9a3013370deaadfac46318feead..226c8ae00d04ea4f20f6bb66536b7eeaadae72e6 100644 (file)
@@ -1473,7 +1473,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
        case AUDIT_SIGNAL_INFO:
                if (lsmprop_is_set(&audit_sig_lsm)) {
                        err = security_lsmprop_to_secctx(&audit_sig_lsm,
-                                                        &lsmctx);
+                                                        &lsmctx, LSM_ID_UNDEF);
                        if (err < 0)
                                return err;
                }
@@ -2188,7 +2188,7 @@ int audit_log_task_context(struct audit_buffer *ab)
        if (!lsmprop_is_set(&prop))
                return 0;
 
-       error = security_lsmprop_to_secctx(&prop, &ctx);
+       error = security_lsmprop_to_secctx(&prop, &ctx, LSM_ID_UNDEF);
        if (error < 0) {
                if (error != -EINVAL)
                        goto error_path;
index 8ec768e2c1e5ebd83c092fe31ead904c0e47821f..3b606fd4ae8e8749553c4ca4d33b6dfa74f66e99 100644 (file)
@@ -1109,7 +1109,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
                         from_kuid(&init_user_ns, auid),
                         from_kuid(&init_user_ns, uid), sessionid);
        if (lsmprop_is_set(prop)) {
-               if (security_lsmprop_to_secctx(prop, &ctx) < 0) {
+               if (security_lsmprop_to_secctx(prop, &ctx, LSM_ID_UNDEF) < 0) {
                        audit_log_format(ab, " obj=(none)");
                        rc = 1;
                } else {
@@ -1395,7 +1395,8 @@ static void show_special(struct audit_context *context, int *call_panic)
                        struct lsm_context lsmctx;
 
                        if (security_lsmprop_to_secctx(&context->ipc.oprop,
-                                                      &lsmctx) < 0) {
+                                                      &lsmctx,
+                                                      LSM_ID_UNDEF) < 0) {
                                *call_panic = 1;
                        } else {
                                audit_log_format(ab, " obj=%s", lsmctx.context);
@@ -1560,7 +1561,8 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
        if (lsmprop_is_set(&n->oprop)) {
                struct lsm_context ctx;
 
-               if (security_lsmprop_to_secctx(&n->oprop, &ctx) < 0) {
+               if (security_lsmprop_to_secctx(&n->oprop, &ctx,
+                                              LSM_ID_UNDEF) < 0) {
                        if (call_panic)
                                *call_panic = 2;
                } else {
index 0d04d23aafe7fcc43db96331450535919a06b964..6d6545297ee30b1b3c0b000de2c74ab6c72c4d74 100644 (file)
@@ -98,7 +98,8 @@ struct audit_buffer *netlbl_audit_start_common(int type,
                         audit_info->sessionid);
 
        if (lsmprop_is_set(&audit_info->prop) &&
-           security_lsmprop_to_secctx(&audit_info->prop, &ctx) > 0) {
+           security_lsmprop_to_secctx(&audit_info->prop, &ctx,
+                                      LSM_ID_UNDEF) > 0) {
                audit_log_format(audit_buf, " subj=%s", ctx.context);
                security_release_secctx(&ctx);
        }
index ad163f06bf7abc4327f9918f11b903e1649ef35e..dd588f548a2b0c8c8761e167a471540fa54af5e0 100644 (file)
@@ -4342,17 +4342,31 @@ EXPORT_SYMBOL(security_secid_to_secctx);
  * security_lsmprop_to_secctx() - Convert a lsm_prop to a secctx
  * @prop: lsm specific information
  * @cp: the LSM context
+ * @lsmid: which security module to report
  *
  * Convert a @prop entry to security context.  If @cp is NULL the
  * length of the result 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 @cp.
  *
+ * @lsmid identifies which LSM should supply the context.
+ * A value of LSM_ID_UNDEF indicates that the first LSM suppling
+ * the hook should be used. This is used in cases where the
+ * ID of the supplying LSM is unambiguous.
+ *
  * Return: Return length of data on success, error on failure.
  */
-int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp)
+int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp,
+                              int lsmid)
 {
-       return call_int_hook(lsmprop_to_secctx, prop, cp);
+       struct lsm_static_call *scall;
+
+       lsm_for_each_hook(scall, lsmprop_to_secctx) {
+               if (lsmid != LSM_ID_UNDEF && lsmid != scall->hl->lsmid->id)
+                       continue;
+               return scall->hl->hook.lsmprop_to_secctx(prop, cp);
+       }
+       return LSM_RET_DEFAULT(lsmprop_to_secctx);
 }
 EXPORT_SYMBOL(security_lsmprop_to_secctx);