]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
audit: maintain an lsm_prop in audit_context
authorCasey Schaufler <casey@schaufler-ca.com>
Wed, 9 Oct 2024 17:32:12 +0000 (10:32 -0700)
committerPaul Moore <paul@paul-moore.com>
Fri, 11 Oct 2024 18:34:13 +0000 (14:34 -0400)
Replace the secid value stored in struct audit_context with a struct
lsm_prop. Change the code that uses this value to accommodate the
change. security_audit_rule_match() expects a lsm_prop, so existing
scaffolding can be removed. A call to security_secid_to_secctx()
is changed to security_lsmprop_to_secctx().  The call to
security_ipc_getsecid() is scaffolded.

A new function lsmprop_is_set() is introduced to identify whether
an lsm_prop contains a non-zero value.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
[PM: subject line tweak, fix lsmprop_is_set() typo]
Signed-off-by: Paul Moore <paul@paul-moore.com>
include/linux/security.h
kernel/audit.h
kernel/auditsc.c

index f1c68e38b15d8970992b31cd66555e7b2418bea6..c029bfe2c5bb8a0a650c6a40f7372d4c8925f970 100644 (file)
@@ -291,6 +291,19 @@ static inline const char *kernel_load_data_id_str(enum kernel_load_data_id id)
 
 #ifdef CONFIG_SECURITY
 
+/**
+ * lsmprop_is_set - report if there is a value in the lsm_prop
+ * @prop: Pointer to the exported LSM data
+ *
+ * Returns true if there is a value set, false otherwise
+ */
+static inline bool lsmprop_is_set(struct lsm_prop *prop)
+{
+       const struct lsm_prop empty = {};
+
+       return !!memcmp(prop, &empty, sizeof(*prop));
+}
+
 int call_blocking_lsm_notifier(enum lsm_event event, void *data);
 int register_blocking_lsm_notifier(struct notifier_block *nb);
 int unregister_blocking_lsm_notifier(struct notifier_block *nb);
@@ -552,6 +565,17 @@ int security_bdev_setintegrity(struct block_device *bdev,
                               size_t size);
 #else /* CONFIG_SECURITY */
 
+/**
+ * lsmprop_is_set - report if there is a value in the lsm_prop
+ * @prop: Pointer to the exported LSM data
+ *
+ * Returns true if there is a value set, false otherwise
+ */
+static inline bool lsmprop_is_set(struct lsm_prop *prop)
+{
+       return false;
+}
+
 static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data)
 {
        return 0;
index a60d2840559e2bda51bd2db82e62474886490996..d14924a887c9a9d66c6174f1dd2d9c2fe5a642df 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/fs.h>
 #include <linux/audit.h>
+#include <linux/security.h>
 #include <linux/skbuff.h>
 #include <uapi/linux/mqueue.h>
 #include <linux/tty.h>
@@ -160,7 +161,7 @@ struct audit_context {
                        kuid_t                  uid;
                        kgid_t                  gid;
                        umode_t                 mode;
-                       u32                     osid;
+                       struct lsm_prop         oprop;
                        int                     has_perm;
                        uid_t                   perm_uid;
                        gid_t                   perm_gid;
index aaf672a962d6a1ca289fd24605f4faca82ccb395..d92326215f6517a5aa0d82517ef1bc97c3c588da 100644 (file)
@@ -724,9 +724,7 @@ static int audit_filter_rules(struct task_struct *tsk,
                                /* Find ipc objects that match */
                                if (!ctx || ctx->type != AUDIT_IPC)
                                        break;
-                               /* scaffolding */
-                               prop.scaffold.secid = ctx->ipc.osid;
-                               if (security_audit_rule_match(&prop,
+                               if (security_audit_rule_match(&ctx->ipc.oprop,
                                                              f->type, f->op,
                                                              f->lsm_rule))
                                        ++result;
@@ -1394,19 +1392,17 @@ static void show_special(struct audit_context *context, int *call_panic)
                        audit_log_format(ab, " a%d=%lx", i,
                                context->socketcall.args[i]);
                break; }
-       case AUDIT_IPC: {
-               u32 osid = context->ipc.osid;
-
+       case AUDIT_IPC:
                audit_log_format(ab, "ouid=%u ogid=%u mode=%#ho",
                                 from_kuid(&init_user_ns, context->ipc.uid),
                                 from_kgid(&init_user_ns, context->ipc.gid),
                                 context->ipc.mode);
-               if (osid) {
+               if (lsmprop_is_set(&context->ipc.oprop)) {
                        char *ctx = NULL;
                        u32 len;
 
-                       if (security_secid_to_secctx(osid, &ctx, &len)) {
-                               audit_log_format(ab, " osid=%u", osid);
+                       if (security_lsmprop_to_secctx(&context->ipc.oprop,
+                                                      &ctx, &len)) {
                                *call_panic = 1;
                        } else {
                                audit_log_format(ab, " obj=%s", ctx);
@@ -1426,7 +1422,7 @@ static void show_special(struct audit_context *context, int *call_panic)
                                context->ipc.perm_gid,
                                context->ipc.perm_mode);
                }
-               break; }
+               break;
        case AUDIT_MQ_OPEN:
                audit_log_format(ab,
                        "oflag=0x%x mode=%#ho mq_flags=0x%lx mq_maxmsg=%ld "
@@ -2642,7 +2638,8 @@ void __audit_ipc_obj(struct kern_ipc_perm *ipcp)
        context->ipc.gid = ipcp->gid;
        context->ipc.mode = ipcp->mode;
        context->ipc.has_perm = 0;
-       security_ipc_getsecid(ipcp, &context->ipc.osid);
+       /* scaffolding */
+       security_ipc_getsecid(ipcp, &context->ipc.oprop.scaffold.secid);
        context->type = AUDIT_IPC;
 }