linux-security-module.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/6] Audit: Records for multiple security contexts
       [not found] <20250307183701.16970-1-casey.ref@schaufler-ca.com>
@ 2025-03-07 18:36 ` Casey Schaufler
  2025-03-07 18:36   ` [PATCH v2 1/6] Audit: Create audit_stamp structure Casey Schaufler
                     ` (5 more replies)
  0 siblings, 6 replies; 18+ messages in thread
From: Casey Schaufler @ 2025-03-07 18:36 UTC (permalink / raw)
  To: casey, paul, eparis, linux-security-module, audit
  Cc: jmorris, serge, keescook, john.johansen, penguin-kernel,
	stephen.smalley.work, linux-kernel, selinux

The Linux audit system includes LSM based security "context" information
in its events. Historically, only one LSM that uses security contexts can
be active on a system. One of the few obsticles to allowing multiple LSM
support is the inability to report more than one security context in an
audit event. This patchset provides a mechanism to provide supplimental
records containing more than one security context for subjects and
objects. 
  
The mechanism for reporting multiple security contexts inspired
considerable discussion. It would have been possible to add multiple
contexts to existing records using sophisticated formatting. This would
have significant backward compatibility issues, and require additional
parsing in user space code. Adding new records for an event that contain
the contexts is more in keeping with the way audit events have been
constructed in the past.
 
Only audit events associated with system calls have required multiple
records prior to this. Mechanism has been added allowing any event
to be composed of multiple records. This should make it easier to
add information to existing audit events without breaking backward
compatability.
 
v2:
Maintain separate counts for LSMs using subject contexts and object
contexts. AppArmor uses the former but not the latter.
Correct error handling in object record creation.

https://github.com/cschaufler/lsm-stacking#audit-records-multiple-contexts-v2

Casey Schaufler (6):
  Audit: Create audit_stamp structure
  Audit: Allow multiple records in an audit_buffer
  LSM: security_lsmblob_to_secctx module selection
  Audit: Add record for multiple task security contexts
  Audit: multiple subject lsm values for netlabel
  Audit: Add record for multiple object contexts

 include/linux/audit.h        |  13 ++
 include/linux/lsm_hooks.h    |   4 +
 include/linux/security.h     |   8 +-
 include/uapi/linux/audit.h   |   2 +
 kernel/audit.c               | 235 +++++++++++++++++++++++++++++------
 kernel/audit.h               |  13 +-
 kernel/auditsc.c             |  65 +++-------
 net/netlabel/netlabel_user.c |   8 +-
 security/apparmor/lsm.c      |   1 +
 security/bpf/hooks.c         |   1 +
 security/security.c          |  19 ++-
 security/selinux/hooks.c     |   2 +
 security/smack/smack_lsm.c   |   2 +
 13 files changed, 274 insertions(+), 99 deletions(-)

-- 
2.47.0


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2 1/6] Audit: Create audit_stamp structure
  2025-03-07 18:36 ` [PATCH v2 0/6] Audit: Records for multiple security contexts Casey Schaufler
@ 2025-03-07 18:36   ` Casey Schaufler
  2025-03-12 23:51     ` Paul Moore
  2025-03-07 18:36   ` [PATCH v2 2/6] Audit: Allow multiple records in an audit_buffer Casey Schaufler
                     ` (4 subsequent siblings)
  5 siblings, 1 reply; 18+ messages in thread
From: Casey Schaufler @ 2025-03-07 18:36 UTC (permalink / raw)
  To: casey, paul, eparis, linux-security-module, audit
  Cc: jmorris, serge, keescook, john.johansen, penguin-kernel,
	stephen.smalley.work, linux-kernel, selinux

Replace the timestamp and serial number pair used in audit records
with a structure containing the two elements.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
 kernel/audit.c   | 17 +++++++++--------
 kernel/audit.h   | 13 +++++++++----
 kernel/auditsc.c | 22 +++++++++-------------
 3 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/kernel/audit.c b/kernel/audit.c
index 5f5bf85bcc90..2a567f667528 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1833,11 +1833,11 @@ unsigned int audit_serial(void)
 }
 
 static inline void audit_get_stamp(struct audit_context *ctx,
-				   struct timespec64 *t, unsigned int *serial)
+				   struct audit_stamp *stamp)
 {
-	if (!ctx || !auditsc_get_stamp(ctx, t, serial)) {
-		ktime_get_coarse_real_ts64(t);
-		*serial = audit_serial();
+	if (!ctx || !auditsc_get_stamp(ctx, stamp)) {
+		ktime_get_coarse_real_ts64(&stamp->ctime);
+		stamp->serial = audit_serial();
 	}
 }
 
@@ -1860,8 +1860,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
 				     int type)
 {
 	struct audit_buffer *ab;
-	struct timespec64 t;
-	unsigned int serial;
+	struct audit_stamp stamp;
 
 	if (audit_initialized != AUDIT_INITIALIZED)
 		return NULL;
@@ -1916,12 +1915,14 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
 		return NULL;
 	}
 
-	audit_get_stamp(ab->ctx, &t, &serial);
+	audit_get_stamp(ab->ctx, &stamp);
 	/* cancel dummy context to enable supporting records */
 	if (ctx)
 		ctx->dummy = 0;
 	audit_log_format(ab, "audit(%llu.%03lu:%u): ",
-			 (unsigned long long)t.tv_sec, t.tv_nsec/1000000, serial);
+			 (unsigned long long)stamp.ctime.tv_sec,
+			 stamp.ctime.tv_nsec/1000000,
+			 stamp.serial);
 
 	return ab;
 }
diff --git a/kernel/audit.h b/kernel/audit.h
index 0211cb307d30..4d6dd2588f9b 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -99,6 +99,12 @@ struct audit_proctitle {
 	char	*value;	/* the cmdline field */
 };
 
+/* A timestamp/serial pair to identify an event */
+struct audit_stamp {
+	struct timespec64	ctime;	/* time of syscall entry */
+	unsigned int		serial;	/* serial number for record */
+};
+
 /* The per-task audit context. */
 struct audit_context {
 	int		    dummy;	/* must be the first element */
@@ -108,10 +114,9 @@ struct audit_context {
 		AUDIT_CTX_URING,	/* in use by io_uring */
 	} context;
 	enum audit_state    state, current_state;
-	unsigned int	    serial;     /* serial number for record */
+	struct audit_stamp  stamp;	/* event identifier */
 	int		    major;      /* syscall number */
 	int		    uring_op;   /* uring operation */
-	struct timespec64   ctime;      /* time of syscall entry */
 	unsigned long	    argv[4];    /* syscall arguments */
 	long		    return_code;/* syscall return code */
 	u64		    prio;
@@ -263,7 +268,7 @@ extern void audit_put_tty(struct tty_struct *tty);
 extern unsigned int audit_serial(void);
 #ifdef CONFIG_AUDITSYSCALL
 extern int auditsc_get_stamp(struct audit_context *ctx,
-			      struct timespec64 *t, unsigned int *serial);
+			     struct audit_stamp *stamp);
 
 extern void audit_put_watch(struct audit_watch *watch);
 extern void audit_get_watch(struct audit_watch *watch);
@@ -304,7 +309,7 @@ extern void audit_filter_inodes(struct task_struct *tsk,
 				struct audit_context *ctx);
 extern struct list_head *audit_killed_trees(void);
 #else /* CONFIG_AUDITSYSCALL */
-#define auditsc_get_stamp(c, t, s) 0
+#define auditsc_get_stamp(c, s) 0
 #define audit_put_watch(w) do { } while (0)
 #define audit_get_watch(w) do { } while (0)
 #define audit_to_watch(k, p, l, o) (-EINVAL)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 9c853cde9abe..2ec3a0d85447 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -994,10 +994,10 @@ static void audit_reset_context(struct audit_context *ctx)
 	 */
 
 	ctx->current_state = ctx->state;
-	ctx->serial = 0;
+	ctx->stamp.serial = 0;
 	ctx->major = 0;
 	ctx->uring_op = 0;
-	ctx->ctime = (struct timespec64){ .tv_sec = 0, .tv_nsec = 0 };
+	ctx->stamp.ctime = (struct timespec64){ .tv_sec = 0, .tv_nsec = 0 };
 	memset(ctx->argv, 0, sizeof(ctx->argv));
 	ctx->return_code = 0;
 	ctx->prio = (ctx->state == AUDIT_STATE_RECORD ? ~0ULL : 0);
@@ -1917,7 +1917,7 @@ void __audit_uring_entry(u8 op)
 
 	ctx->context = AUDIT_CTX_URING;
 	ctx->current_state = ctx->state;
-	ktime_get_coarse_real_ts64(&ctx->ctime);
+	ktime_get_coarse_real_ts64(&ctx->stamp.ctime);
 }
 
 /**
@@ -2039,7 +2039,7 @@ void __audit_syscall_entry(int major, unsigned long a1, unsigned long a2,
 	context->argv[3]    = a4;
 	context->context = AUDIT_CTX_SYSCALL;
 	context->current_state  = state;
-	ktime_get_coarse_real_ts64(&context->ctime);
+	ktime_get_coarse_real_ts64(&context->stamp.ctime);
 }
 
 /**
@@ -2510,21 +2510,17 @@ EXPORT_SYMBOL_GPL(__audit_inode_child);
 /**
  * auditsc_get_stamp - get local copies of audit_context values
  * @ctx: audit_context for the task
- * @t: timespec64 to store time recorded in the audit_context
- * @serial: serial value that is recorded in the audit_context
+ * @stamp: timestamp to record
  *
  * Also sets the context as auditable.
  */
-int auditsc_get_stamp(struct audit_context *ctx,
-		       struct timespec64 *t, unsigned int *serial)
+int auditsc_get_stamp(struct audit_context *ctx, struct audit_stamp *stamp)
 {
 	if (ctx->context == AUDIT_CTX_UNUSED)
 		return 0;
-	if (!ctx->serial)
-		ctx->serial = audit_serial();
-	t->tv_sec  = ctx->ctime.tv_sec;
-	t->tv_nsec = ctx->ctime.tv_nsec;
-	*serial    = ctx->serial;
+	if (!ctx->stamp.serial)
+		ctx->stamp.serial = audit_serial();
+	*stamp = ctx->stamp;
 	if (!ctx->prio) {
 		ctx->prio = 1;
 		ctx->current_state = AUDIT_STATE_RECORD;
-- 
2.47.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v2 2/6] Audit: Allow multiple records in an audit_buffer
  2025-03-07 18:36 ` [PATCH v2 0/6] Audit: Records for multiple security contexts Casey Schaufler
  2025-03-07 18:36   ` [PATCH v2 1/6] Audit: Create audit_stamp structure Casey Schaufler
@ 2025-03-07 18:36   ` Casey Schaufler
  2025-03-12 23:51     ` Paul Moore
  2025-03-07 18:36   ` [PATCH v2 3/6] LSM: security_lsmblob_to_secctx module selection Casey Schaufler
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 18+ messages in thread
From: Casey Schaufler @ 2025-03-07 18:36 UTC (permalink / raw)
  To: casey, paul, eparis, linux-security-module, audit
  Cc: jmorris, serge, keescook, john.johansen, penguin-kernel,
	stephen.smalley.work, linux-kernel, selinux

Replace the single skb pointer in an audit_buffer with
a list of skb pointers. Add the audit_stamp information
to the audit_buffer as there's no guarantee that there
will be an audit_context containing the stamp associated
with the event. At audit_log_end() time create auxiliary
records (none are currently defined) as have been added
to the list. Functions are created to manage the skb list
in the audit_buffer.

Suggested-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
 kernel/audit.c | 111 +++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 89 insertions(+), 22 deletions(-)

diff --git a/kernel/audit.c b/kernel/audit.c
index 2a567f667528..a4945f1c3ec0 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -195,8 +195,10 @@ static struct audit_ctl_mutex {
  * to place it on a transmit queue.  Multiple audit_buffers can be in
  * use simultaneously. */
 struct audit_buffer {
-	struct sk_buff       *skb;	/* formatted skb ready to send */
+	struct sk_buff       *skb;	/* the skb for audit_log functions */
+	struct sk_buff_head  skb_list;	/* formatted skbs, ready to send */
 	struct audit_context *ctx;	/* NULL or associated context */
+	struct audit_stamp   stamp;	/* audit stamp for these records */
 	gfp_t		     gfp_mask;
 };
 
@@ -1776,10 +1778,13 @@ __setup("audit_backlog_limit=", audit_backlog_limit_set);
 
 static void audit_buffer_free(struct audit_buffer *ab)
 {
+	struct sk_buff *skb;
+
 	if (!ab)
 		return;
 
-	kfree_skb(ab->skb);
+	while ((skb = skb_dequeue(&ab->skb_list)))
+		kfree_skb(skb);
 	kmem_cache_free(audit_buffer_cache, ab);
 }
 
@@ -1795,6 +1800,10 @@ static struct audit_buffer *audit_buffer_alloc(struct audit_context *ctx,
 	ab->skb = nlmsg_new(AUDIT_BUFSIZ, gfp_mask);
 	if (!ab->skb)
 		goto err;
+
+	skb_queue_head_init(&ab->skb_list);
+	skb_queue_tail(&ab->skb_list, ab->skb);
+
 	if (!nlmsg_put(ab->skb, 0, 0, type, 0, 0))
 		goto err;
 
@@ -1860,7 +1869,6 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
 				     int type)
 {
 	struct audit_buffer *ab;
-	struct audit_stamp stamp;
 
 	if (audit_initialized != AUDIT_INITIALIZED)
 		return NULL;
@@ -1915,14 +1923,14 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
 		return NULL;
 	}
 
-	audit_get_stamp(ab->ctx, &stamp);
+	audit_get_stamp(ab->ctx, &ab->stamp);
 	/* cancel dummy context to enable supporting records */
 	if (ctx)
 		ctx->dummy = 0;
 	audit_log_format(ab, "audit(%llu.%03lu:%u): ",
-			 (unsigned long long)stamp.ctime.tv_sec,
-			 stamp.ctime.tv_nsec/1000000,
-			 stamp.serial);
+			 (unsigned long long)ab->stamp.ctime.tv_sec,
+			 ab->stamp.ctime.tv_nsec/1000000,
+			 ab->stamp.serial);
 
 	return ab;
 }
@@ -2178,6 +2186,57 @@ void audit_log_key(struct audit_buffer *ab, char *key)
 		audit_log_format(ab, "(null)");
 }
 
+/**
+ * audit_buffer_aux_new - Add an aux record buffer to the skb list
+ * @ab: audit_buffer
+ * @type: message type
+ *
+ * Aux records are allocated and added to the skb list of
+ * the "main" record. The ab->skb is reset to point to the
+ * aux record on its creation. When the aux record in complete
+ * ab->skb has to be reset to point to the "main" record.
+ * This allows the audit_log_ functions to be ignorant of
+ * which kind of record it is logging to. It also avoids adding
+ * special data for aux records.
+ *
+ * On success ab->skb will point to the new aux record.
+ * Returns 0 on success, -ENOMEM should allocation fail.
+ */
+static int audit_buffer_aux_new(struct audit_buffer *ab, int type)
+{
+	WARN_ON(ab->skb != skb_peek(&ab->skb_list));
+
+	ab->skb = nlmsg_new(AUDIT_BUFSIZ, ab->gfp_mask);
+	if (!ab->skb)
+		goto err;
+	if (!nlmsg_put(ab->skb, 0, 0, type, 0, 0))
+		goto err;
+	skb_queue_tail(&ab->skb_list, ab->skb);
+
+	audit_log_format(ab, "audit(%llu.%03lu:%u): ",
+			 (unsigned long long)ab->stamp.ctime.tv_sec,
+			 ab->stamp.ctime.tv_nsec/1000000,
+			 ab->stamp.serial);
+
+	return 0;
+
+err:
+	kfree_skb(ab->skb);
+	ab->skb = skb_peek(&ab->skb_list);
+	return -ENOMEM;
+}
+
+/**
+ * audit_buffer_aux_end - Switch back to the "main" record from an aux record
+ * @ab: audit_buffer
+ *
+ * Restores the "main" audit record to ab->skb.
+ */
+static void audit_buffer_aux_end(struct audit_buffer *ab)
+{
+	ab->skb = skb_peek(&ab->skb_list);
+}
+
 int audit_log_task_context(struct audit_buffer *ab)
 {
 	struct lsm_prop prop;
@@ -2412,26 +2471,14 @@ int audit_signal_info(int sig, struct task_struct *t)
 }
 
 /**
- * audit_log_end - end one audit record
- * @ab: the audit_buffer
- *
- * We can not do a netlink send inside an irq context because it blocks (last
- * arg, flags, is not set to MSG_DONTWAIT), so the audit buffer is placed on a
- * queue and a kthread is scheduled to remove them from the queue outside the
- * irq context.  May be called in any context.
+ * __audit_log_end - enqueue one audit record
+ * @skb: the buffer to send
  */
-void audit_log_end(struct audit_buffer *ab)
+static void __audit_log_end(struct sk_buff *skb)
 {
-	struct sk_buff *skb;
 	struct nlmsghdr *nlh;
 
-	if (!ab)
-		return;
-
 	if (audit_rate_check()) {
-		skb = ab->skb;
-		ab->skb = NULL;
-
 		/* setup the netlink header, see the comments in
 		 * kauditd_send_multicast_skb() for length quirks */
 		nlh = nlmsg_hdr(skb);
@@ -2442,6 +2489,26 @@ void audit_log_end(struct audit_buffer *ab)
 		wake_up_interruptible(&kauditd_wait);
 	} else
 		audit_log_lost("rate limit exceeded");
+}
+
+/**
+ * audit_log_end - end one audit record
+ * @ab: the audit_buffer
+ *
+ * We can not do a netlink send inside an irq context because it blocks (last
+ * arg, flags, is not set to MSG_DONTWAIT), so the audit buffer is placed on a
+ * queue and a kthread is scheduled to remove them from the queue outside the
+ * irq context.  May be called in any context.
+ */
+void audit_log_end(struct audit_buffer *ab)
+{
+	struct sk_buff *skb;
+
+	if (!ab)
+		return;
+
+	while ((skb = skb_dequeue(&ab->skb_list)))
+		__audit_log_end(skb);
 
 	audit_buffer_free(ab);
 }
-- 
2.47.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v2 3/6] LSM: security_lsmblob_to_secctx module selection
  2025-03-07 18:36 ` [PATCH v2 0/6] Audit: Records for multiple security contexts Casey Schaufler
  2025-03-07 18:36   ` [PATCH v2 1/6] Audit: Create audit_stamp structure Casey Schaufler
  2025-03-07 18:36   ` [PATCH v2 2/6] Audit: Allow multiple records in an audit_buffer Casey Schaufler
@ 2025-03-07 18:36   ` Casey Schaufler
  2025-03-08 15:52     ` kernel test robot
  2025-03-12 23:51     ` Paul Moore
  2025-03-07 18:36   ` [PATCH v2 4/6] Audit: Add record for multiple task security contexts Casey Schaufler
                     ` (2 subsequent siblings)
  5 siblings, 2 replies; 18+ messages in thread
From: Casey Schaufler @ 2025-03-07 18:36 UTC (permalink / raw)
  To: casey, paul, eparis, linux-security-module, audit
  Cc: jmorris, serge, keescook, john.johansen, penguin-kernel,
	stephen.smalley.work, linux-kernel, selinux

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>
---
 include/linux/security.h     |  6 ++++--
 kernel/audit.c               |  4 ++--
 kernel/auditsc.c             |  8 +++++---
 net/netlabel/netlabel_user.c |  3 ++-
 security/security.c          | 13 +++++++++++--
 5 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index 980b6c207cad..540894695c4b 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -566,7 +566,8 @@ 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, 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);
@@ -1543,7 +1544,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;
 }
diff --git a/kernel/audit.c b/kernel/audit.c
index a4945f1c3ec0..293364bba961 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1475,7 +1475,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;
 		}
@@ -2247,7 +2247,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;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 2ec3a0d85447..d98ce7097a2d 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -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 {
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c
index 0d04d23aafe7..6d6545297ee3 100644
--- a/net/netlabel/netlabel_user.c
+++ b/net/netlabel/netlabel_user.c
@@ -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);
 	}
diff --git a/security/security.c b/security/security.c
index 143561ebc3e8..55f9c7ad3f89 100644
--- a/security/security.c
+++ b/security/security.c
@@ -4312,6 +4312,7 @@ EXPORT_SYMBOL(security_ismaclabel);
  * security_secid_to_secctx() - Convert a secid to a secctx
  * @secid: secid
  * @cp: the LSM context
+ * @lsmid: which security module to report
  *
  * Convert secid to security context.  If @cp is NULL the length of the
  * result will be returned, but no data will be returned.  This
@@ -4338,9 +4339,17 @@ EXPORT_SYMBOL(security_secid_to_secctx);
  *
  * 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 != 0 && 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);
 
-- 
2.47.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v2 4/6] Audit: Add record for multiple task security contexts
  2025-03-07 18:36 ` [PATCH v2 0/6] Audit: Records for multiple security contexts Casey Schaufler
                     ` (2 preceding siblings ...)
  2025-03-07 18:36   ` [PATCH v2 3/6] LSM: security_lsmblob_to_secctx module selection Casey Schaufler
@ 2025-03-07 18:36   ` Casey Schaufler
  2025-03-12 23:51     ` Paul Moore
  2025-03-07 18:37   ` [PATCH v2 5/6] Audit: multiple subject lsm values for netlabel Casey Schaufler
  2025-03-07 18:37   ` [PATCH v2 6/6] Audit: Add record for multiple object contexts Casey Schaufler
  5 siblings, 1 reply; 18+ messages in thread
From: Casey Schaufler @ 2025-03-07 18:36 UTC (permalink / raw)
  To: casey, paul, eparis, linux-security-module, audit
  Cc: jmorris, serge, keescook, john.johansen, penguin-kernel,
	stephen.smalley.work, linux-kernel, selinux

Create a new audit record AUDIT_MAC_TASK_CONTEXTS.
An example of the MAC_TASK_CONTEXTS (1423) record is:

    type=MAC_TASK_CONTEXTS[1423]
    msg=audit(1600880931.832:113)
    subj_apparmor=unconfined
    subj_smack=_

When an audit event includes a AUDIT_MAC_TASK_CONTEXTS record
the "subj=" field in other records in the event will be "subj=?".
An AUDIT_MAC_TASK_CONTEXTS record is supplied when the system has
multiple security modules that may make access decisions based
on a subject security context.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
 include/linux/lsm_hooks.h  |  1 +
 include/linux/security.h   |  1 +
 include/uapi/linux/audit.h |  1 +
 kernel/audit.c             | 45 ++++++++++++++++++++++++++++++++------
 security/apparmor/lsm.c    |  1 +
 security/bpf/hooks.c       |  1 +
 security/security.c        |  3 +++
 security/selinux/hooks.c   |  1 +
 security/smack/smack_lsm.c |  1 +
 9 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 090d1d3e19fe..e4d303ab1f20 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -81,6 +81,7 @@ struct lsm_static_calls_table {
 struct lsm_id {
 	const char *name;
 	u64 id;
+	bool subjctx;
 };
 
 /*
diff --git a/include/linux/security.h b/include/linux/security.h
index 540894695c4b..79a9bf4a7cdd 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -168,6 +168,7 @@ struct lsm_prop {
 
 extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1];
 extern u32 lsm_active_cnt;
+extern u32 lsm_subjctx_cnt;
 extern const struct lsm_id *lsm_idlist[];
 
 /* These functions are in security/commoncap.c */
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index d9a069b4a775..5ebb5d80363d 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -146,6 +146,7 @@
 #define AUDIT_IPE_ACCESS	1420	/* IPE denial or grant */
 #define AUDIT_IPE_CONFIG_CHANGE	1421	/* IPE config change */
 #define AUDIT_IPE_POLICY_LOAD	1422	/* IPE policy load */
+#define AUDIT_MAC_TASK_CONTEXTS	1423	/* Multiple LSM task contexts */
 
 #define AUDIT_FIRST_KERN_ANOM_MSG   1700
 #define AUDIT_LAST_KERN_ANOM_MSG    1799
diff --git a/kernel/audit.c b/kernel/audit.c
index 293364bba961..59eaf69ee8ac 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -54,6 +54,7 @@
 #include <net/netlink.h>
 #include <linux/skbuff.h>
 #include <linux/security.h>
+#include <linux/lsm_hooks.h>
 #include <linux/freezer.h>
 #include <linux/pid_namespace.h>
 #include <net/netns/generic.h>
@@ -2241,21 +2242,51 @@ int audit_log_task_context(struct audit_buffer *ab)
 {
 	struct lsm_prop prop;
 	struct lsm_context ctx;
+	bool space = false;
 	int error;
+	int i;
 
 	security_current_getlsmprop_subj(&prop);
 	if (!lsmprop_is_set(&prop))
 		return 0;
 
-	error = security_lsmprop_to_secctx(&prop, &ctx, LSM_ID_UNDEF);
-	if (error < 0) {
-		if (error != -EINVAL)
-			goto error_path;
+	if (lsm_subjctx_cnt < 2) {
+		error = security_lsmprop_to_secctx(&prop, &ctx, LSM_ID_UNDEF);
+		if (error < 0) {
+			if (error != -EINVAL)
+				goto error_path;
+			return 0;
+		}
+		audit_log_format(ab, " subj=%s", ctx.context);
+		security_release_secctx(&ctx);
 		return 0;
 	}
-
-	audit_log_format(ab, " subj=%s", ctx.context);
-	security_release_secctx(&ctx);
+	/* Multiple LSMs provide contexts. Include an aux record. */
+	audit_log_format(ab, " subj=?");
+	error = audit_buffer_aux_new(ab, AUDIT_MAC_TASK_CONTEXTS);
+	if (error)
+		goto error_path;
+
+	for (i = 0; i < lsm_active_cnt; i++) {
+		if (!lsm_idlist[i]->subjctx)
+			continue;
+		error = security_lsmprop_to_secctx(&prop, &ctx,
+						   lsm_idlist[i]->id);
+		if (error < 0) {
+			if (error == -EOPNOTSUPP)
+				continue;
+			audit_log_format(ab, "%ssubj_%s=?", space ? " " : "",
+					 lsm_idlist[i]->name);
+			if (error != -EINVAL)
+				audit_panic("error in audit_log_task_context");
+		} else {
+			audit_log_format(ab, "%ssubj_%s=%s", space ? " " : "",
+					 lsm_idlist[i]->name, ctx.context);
+			security_release_secctx(&ctx);
+		}
+		space = true;
+	}
+	audit_buffer_aux_end(ab);
 	return 0;
 
 error_path:
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 9b6c2f157f83..17ec93a8d3fc 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -1427,6 +1427,7 @@ struct lsm_blob_sizes apparmor_blob_sizes __ro_after_init = {
 static const struct lsm_id apparmor_lsmid = {
 	.name = "apparmor",
 	.id = LSM_ID_APPARMOR,
+	.subjctx = true,
 };
 
 static struct security_hook_list apparmor_hooks[] __ro_after_init = {
diff --git a/security/bpf/hooks.c b/security/bpf/hooks.c
index db759025abe1..aaaa1227ce13 100644
--- a/security/bpf/hooks.c
+++ b/security/bpf/hooks.c
@@ -18,6 +18,7 @@ static struct security_hook_list bpf_lsm_hooks[] __ro_after_init = {
 static const struct lsm_id bpf_lsmid = {
 	.name = "bpf",
 	.id = LSM_ID_BPF,
+	.subjctx = false, /* property exists, but will not be used */
 };
 
 static int __init bpf_lsm_init(void)
diff --git a/security/security.c b/security/security.c
index 55f9c7ad3f89..8450cc5f82d5 100644
--- a/security/security.c
+++ b/security/security.c
@@ -320,6 +320,7 @@ static void __init initialize_lsm(struct lsm_info *lsm)
  * Current index to use while initializing the lsm id list.
  */
 u32 lsm_active_cnt __ro_after_init;
+u32 lsm_subjctx_cnt __ro_after_init;
 const struct lsm_id *lsm_idlist[MAX_LSM_COUNT];
 
 /* Populate ordered LSMs list from comma-separated LSM name list. */
@@ -626,6 +627,8 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
 		if (lsm_active_cnt >= MAX_LSM_COUNT)
 			panic("%s Too many LSMs registered.\n", __func__);
 		lsm_idlist[lsm_active_cnt++] = lsmid;
+		if (lsmid->subjctx)
+			lsm_subjctx_cnt++;
 	}
 
 	for (i = 0; i < count; i++) {
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7b867dfec88b..1e2e1545eb2e 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -7142,6 +7142,7 @@ static int selinux_uring_cmd(struct io_uring_cmd *ioucmd)
 static const struct lsm_id selinux_lsmid = {
 	.name = "selinux",
 	.id = LSM_ID_SELINUX,
+	.subjctx = true,
 };
 
 /*
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 239773cdcdcf..75bd62fe1513 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -5057,6 +5057,7 @@ struct lsm_blob_sizes smack_blob_sizes __ro_after_init = {
 static const struct lsm_id smack_lsmid = {
 	.name = "smack",
 	.id = LSM_ID_SMACK,
+	.subjctx = true,
 };
 
 static struct security_hook_list smack_hooks[] __ro_after_init = {
-- 
2.47.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v2 5/6] Audit: multiple subject lsm values for netlabel
  2025-03-07 18:36 ` [PATCH v2 0/6] Audit: Records for multiple security contexts Casey Schaufler
                     ` (3 preceding siblings ...)
  2025-03-07 18:36   ` [PATCH v2 4/6] Audit: Add record for multiple task security contexts Casey Schaufler
@ 2025-03-07 18:37   ` Casey Schaufler
  2025-03-12 23:51     ` Paul Moore
  2025-03-07 18:37   ` [PATCH v2 6/6] Audit: Add record for multiple object contexts Casey Schaufler
  5 siblings, 1 reply; 18+ messages in thread
From: Casey Schaufler @ 2025-03-07 18:37 UTC (permalink / raw)
  To: casey, paul, eparis, linux-security-module, audit
  Cc: jmorris, serge, keescook, john.johansen, penguin-kernel,
	stephen.smalley.work, linux-kernel, selinux

Refactor audit_log_task_context(), creating a new
audit_log_subject_context(). This is used in netlabel auditing
to provide multiple subject security contexts as necessary.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
 include/linux/audit.h        |  8 ++++++++
 kernel/audit.c               | 21 ++++++++++++++-------
 net/netlabel/netlabel_user.c |  9 +--------
 3 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 0050ef288ab3..ee3e2ce70c45 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -37,6 +37,7 @@ struct audit_watch;
 struct audit_tree;
 struct sk_buff;
 struct kern_ipc_perm;
+struct lsm_prop;
 
 struct audit_krule {
 	u32			pflags;
@@ -185,6 +186,8 @@ extern void		    audit_log_path_denied(int type,
 						  const char *operation);
 extern void		    audit_log_lost(const char *message);
 
+extern int audit_log_subject_context(struct audit_buffer *ab,
+				     struct lsm_prop *blob);
 extern int audit_log_task_context(struct audit_buffer *ab);
 extern void audit_log_task_info(struct audit_buffer *ab);
 
@@ -245,6 +248,11 @@ static inline void audit_log_key(struct audit_buffer *ab, char *key)
 { }
 static inline void audit_log_path_denied(int type, const char *operation)
 { }
+static inline int audit_log_subject_context(struct audit_buffer *ab,
+					    struct lsm_prop *prop)
+{
+	return 0;
+}
 static inline int audit_log_task_context(struct audit_buffer *ab)
 {
 	return 0;
diff --git a/kernel/audit.c b/kernel/audit.c
index 59eaf69ee8ac..f0c1f0c0b250 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2238,20 +2238,18 @@ static void audit_buffer_aux_end(struct audit_buffer *ab)
 	ab->skb = skb_peek(&ab->skb_list);
 }
 
-int audit_log_task_context(struct audit_buffer *ab)
+int audit_log_subject_context(struct audit_buffer *ab, struct lsm_prop *prop)
 {
-	struct lsm_prop prop;
 	struct lsm_context ctx;
 	bool space = false;
 	int error;
 	int i;
 
-	security_current_getlsmprop_subj(&prop);
-	if (!lsmprop_is_set(&prop))
+	if (!lsmprop_is_set(prop))
 		return 0;
 
 	if (lsm_subjctx_cnt < 2) {
-		error = security_lsmprop_to_secctx(&prop, &ctx, LSM_ID_UNDEF);
+		error = security_lsmprop_to_secctx(prop, &ctx, LSM_ID_UNDEF);
 		if (error < 0) {
 			if (error != -EINVAL)
 				goto error_path;
@@ -2270,7 +2268,7 @@ int audit_log_task_context(struct audit_buffer *ab)
 	for (i = 0; i < lsm_active_cnt; i++) {
 		if (!lsm_idlist[i]->subjctx)
 			continue;
-		error = security_lsmprop_to_secctx(&prop, &ctx,
+		error = security_lsmprop_to_secctx(prop, &ctx,
 						   lsm_idlist[i]->id);
 		if (error < 0) {
 			if (error == -EOPNOTSUPP)
@@ -2290,9 +2288,18 @@ int audit_log_task_context(struct audit_buffer *ab)
 	return 0;
 
 error_path:
-	audit_panic("error in audit_log_task_context");
+	audit_panic("error in audit_log_subject_context");
 	return error;
 }
+EXPORT_SYMBOL(audit_log_subject_context);
+
+int audit_log_task_context(struct audit_buffer *ab)
+{
+	struct lsm_prop prop;
+
+	security_current_getlsmprop_subj(&prop);
+	return audit_log_subject_context(ab, &prop);
+}
 EXPORT_SYMBOL(audit_log_task_context);
 
 void audit_log_d_path_exe(struct audit_buffer *ab,
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c
index 6d6545297ee3..3d46ea6a8bb8 100644
--- a/net/netlabel/netlabel_user.c
+++ b/net/netlabel/netlabel_user.c
@@ -84,7 +84,6 @@ struct audit_buffer *netlbl_audit_start_common(int type,
 					       struct netlbl_audit *audit_info)
 {
 	struct audit_buffer *audit_buf;
-	struct lsm_context ctx;
 
 	if (audit_enabled == AUDIT_OFF)
 		return NULL;
@@ -96,13 +95,7 @@ struct audit_buffer *netlbl_audit_start_common(int type,
 	audit_log_format(audit_buf, "netlabel: auid=%u ses=%u",
 			 from_kuid(&init_user_ns, audit_info->loginuid),
 			 audit_info->sessionid);
-
-	if (lsmprop_is_set(&audit_info->prop) &&
-	    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);
-	}
+	audit_log_subject_context(audit_buf, &audit_info->prop);
 
 	return audit_buf;
 }
-- 
2.47.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v2 6/6] Audit: Add record for multiple object contexts
  2025-03-07 18:36 ` [PATCH v2 0/6] Audit: Records for multiple security contexts Casey Schaufler
                     ` (4 preceding siblings ...)
  2025-03-07 18:37   ` [PATCH v2 5/6] Audit: multiple subject lsm values for netlabel Casey Schaufler
@ 2025-03-07 18:37   ` Casey Schaufler
  2025-03-09 14:18     ` kernel test robot
                       ` (3 more replies)
  5 siblings, 4 replies; 18+ messages in thread
From: Casey Schaufler @ 2025-03-07 18:37 UTC (permalink / raw)
  To: casey, paul, eparis, linux-security-module, audit
  Cc: jmorris, serge, keescook, john.johansen, penguin-kernel,
	stephen.smalley.work, linux-kernel, selinux

Create a new audit record AUDIT_MAC_OBJ_CONTEXTS.
An example of the MAC_OBJ_CONTEXTS (1424) record is:

    type=MAC_OBJ_CONTEXTS[1424]
    msg=audit(1601152467.009:1050):
    obj_selinux=unconfined_u:object_r:user_home_t:s0

When an audit event includes a AUDIT_MAC_OBJ_CONTEXTS record
the "obj=" field in other records in the event will be "obj=?".
An AUDIT_MAC_OBJ_CONTEXTS record is supplied when the system has
multiple security modules that may make access decisions based
on an object security context.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
 include/linux/audit.h      |  7 ++++-
 include/linux/lsm_hooks.h  |  3 +++
 include/linux/security.h   |  1 +
 include/uapi/linux/audit.h |  1 +
 kernel/audit.c             | 53 +++++++++++++++++++++++++++++++++++++-
 kernel/auditsc.c           | 45 ++++++++------------------------
 security/security.c        |  3 +++
 security/selinux/hooks.c   |  1 +
 security/smack/smack_lsm.c |  1 +
 9 files changed, 79 insertions(+), 36 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index ee3e2ce70c45..0b17acf459f2 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -186,8 +186,10 @@ extern void		    audit_log_path_denied(int type,
 						  const char *operation);
 extern void		    audit_log_lost(const char *message);
 
+extern int audit_log_object_context(struct audit_buffer *ab,
+				    struct lsm_prop *prop);
 extern int audit_log_subject_context(struct audit_buffer *ab,
-				     struct lsm_prop *blob);
+				     struct lsm_prop *prop);
 extern int audit_log_task_context(struct audit_buffer *ab);
 extern void audit_log_task_info(struct audit_buffer *ab);
 
@@ -248,6 +250,9 @@ static inline void audit_log_key(struct audit_buffer *ab, char *key)
 { }
 static inline void audit_log_path_denied(int type, const char *operation)
 { }
+static inline void audit_log_object_context(struct audit_buffer *ab,
+					    struct lsm_prop *prop)
+{ }
 static inline int audit_log_subject_context(struct audit_buffer *ab,
 					    struct lsm_prop *prop)
 {
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index e4d303ab1f20..464bd8ef4045 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -75,6 +75,8 @@ struct lsm_static_calls_table {
  * struct lsm_id - Identify a Linux Security Module.
  * @lsm: name of the LSM, must be approved by the LSM maintainers
  * @id: LSM ID number from uapi/linux/lsm.h
+ * @subjctx: true if LSM supports a subject context
+ * @objctx: true if LSM supports an object context
  *
  * Contains the information that identifies the LSM.
  */
@@ -82,6 +84,7 @@ struct lsm_id {
 	const char *name;
 	u64 id;
 	bool subjctx;
+	bool objctx;
 };
 
 /*
diff --git a/include/linux/security.h b/include/linux/security.h
index 79a9bf4a7cdd..7c1a6d99e148 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -169,6 +169,7 @@ struct lsm_prop {
 extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1];
 extern u32 lsm_active_cnt;
 extern u32 lsm_subjctx_cnt;
+extern u32 lsm_objctx_cnt;
 extern const struct lsm_id *lsm_idlist[];
 
 /* These functions are in security/commoncap.c */
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 5ebb5d80363d..8ca58144bcc6 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -147,6 +147,7 @@
 #define AUDIT_IPE_CONFIG_CHANGE	1421	/* IPE config change */
 #define AUDIT_IPE_POLICY_LOAD	1422	/* IPE policy load */
 #define AUDIT_MAC_TASK_CONTEXTS	1423	/* Multiple LSM task contexts */
+#define AUDIT_MAC_OBJ_CONTEXTS	1424	/* Multiple LSM objext contexts */
 
 #define AUDIT_FIRST_KERN_ANOM_MSG   1700
 #define AUDIT_LAST_KERN_ANOM_MSG    1799
diff --git a/kernel/audit.c b/kernel/audit.c
index f0c1f0c0b250..054776f29327 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1116,7 +1116,6 @@ static int is_audit_feature_set(int i)
 	return af.features & AUDIT_FEATURE_TO_MASK(i);
 }
 
-
 static int audit_get_feature(struct sk_buff *skb)
 {
 	u32 seq;
@@ -2302,6 +2301,58 @@ int audit_log_task_context(struct audit_buffer *ab)
 }
 EXPORT_SYMBOL(audit_log_task_context);
 
+int audit_log_object_context(struct audit_buffer *ab, struct lsm_prop *prop)
+{
+	int i;
+	int rc;
+	int error = 0;
+	char *space = "";
+	struct lsm_context context;
+
+	if (lsm_objctx_cnt < 2) {
+		error = security_lsmprop_to_secctx(prop, &context,
+						   LSM_ID_UNDEF);
+		if (error < 0) {
+			if (error != -EINVAL)
+				goto error_path;
+			return error;
+		}
+		audit_log_format(ab, " obj=%s", context.context);
+		security_release_secctx(&context);
+		return 0;
+	}
+	audit_log_format(ab, " obj=?");
+	error = audit_buffer_aux_new(ab, AUDIT_MAC_OBJ_CONTEXTS);
+	if (error)
+		goto error_path;
+
+	for (i = 0; i < lsm_active_cnt; i++) {
+		if (!lsm_idlist[i]->objctx)
+			continue;
+		rc = security_lsmprop_to_secctx(prop, &context,
+						lsm_idlist[i]->id);
+		if (rc < 0) {
+			audit_log_format(ab, "%sobj_%s=?", space,
+					 lsm_idlist[i]->name);
+			if (rc != -EINVAL)
+				audit_panic("error in audit_log_object_context");
+			error = rc;
+		} else {
+			audit_log_format(ab, "%sobj_%s=%s", space,
+					 lsm_idlist[i]->name, context.context);
+			security_release_secctx(&context);
+		}
+		space = " ";
+	}
+
+	audit_buffer_aux_end(ab);
+	return error;
+
+error_path:
+	audit_panic("error in audit_log_object_context");
+	return error;
+}
+
 void audit_log_d_path_exe(struct audit_buffer *ab,
 			  struct mm_struct *mm)
 {
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index d98ce7097a2d..82470862ea81 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1098,7 +1098,6 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
 				 char *comm)
 {
 	struct audit_buffer *ab;
-	struct lsm_context ctx;
 	int rc = 0;
 
 	ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
@@ -1108,15 +1107,9 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
 	audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", 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, LSM_ID_UNDEF) < 0) {
-			audit_log_format(ab, " obj=(none)");
-			rc = 1;
-		} else {
-			audit_log_format(ab, " obj=%s", ctx.context);
-			security_release_secctx(&ctx);
-		}
-	}
+	if (lsmprop_is_set(prop) && audit_log_object_context(ab, prop))
+		rc = 1;
+
 	audit_log_format(ab, " ocomm=");
 	audit_log_untrustedstring(ab, comm);
 	audit_log_end(ab);
@@ -1392,16 +1385,8 @@ static void show_special(struct audit_context *context, int *call_panic)
 				 from_kgid(&init_user_ns, context->ipc.gid),
 				 context->ipc.mode);
 		if (lsmprop_is_set(&context->ipc.oprop)) {
-			struct lsm_context lsmctx;
-
-			if (security_lsmprop_to_secctx(&context->ipc.oprop,
-						       &lsmctx,
-						       LSM_ID_UNDEF) < 0) {
+			if (audit_log_object_context(ab, &context->ipc.oprop))
 				*call_panic = 1;
-			} else {
-				audit_log_format(ab, " obj=%s", lsmctx.context);
-				security_release_secctx(&lsmctx);
-			}
 		}
 		if (context->ipc.has_perm) {
 			audit_log_end(ab);
@@ -1558,18 +1543,9 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
 				 from_kgid(&init_user_ns, n->gid),
 				 MAJOR(n->rdev),
 				 MINOR(n->rdev));
-	if (lsmprop_is_set(&n->oprop)) {
-		struct lsm_context ctx;
-
-		if (security_lsmprop_to_secctx(&n->oprop, &ctx,
-					       LSM_ID_UNDEF) < 0) {
-			if (call_panic)
-				*call_panic = 2;
-		} else {
-			audit_log_format(ab, " obj=%s", ctx.context);
-			security_release_secctx(&ctx);
-		}
-	}
+	if (lsmprop_is_set(&n->oprop) &&
+	    audit_log_object_context(ab, &n->oprop))
+		*call_panic = 2;
 
 	/* log the audit_names record type */
 	switch (n->type) {
@@ -1780,15 +1756,16 @@ static void audit_log_exit(void)
 						  axs->target_sessionid[i],
 						  &axs->target_ref[i],
 						  axs->target_comm[i]))
-				call_panic = 1;
+			call_panic = 1;
 	}
 
 	if (context->target_pid &&
 	    audit_log_pid_context(context, context->target_pid,
 				  context->target_auid, context->target_uid,
 				  context->target_sessionid,
-				  &context->target_ref, context->target_comm))
-			call_panic = 1;
+				  &context->target_ref,
+				  context->target_comm))
+		call_panic = 1;
 
 	if (context->pwd.dentry && context->pwd.mnt) {
 		ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
diff --git a/security/security.c b/security/security.c
index 8450cc5f82d5..ed48457f8f24 100644
--- a/security/security.c
+++ b/security/security.c
@@ -321,6 +321,7 @@ static void __init initialize_lsm(struct lsm_info *lsm)
  */
 u32 lsm_active_cnt __ro_after_init;
 u32 lsm_subjctx_cnt __ro_after_init;
+u32 lsm_objctx_cnt __ro_after_init;
 const struct lsm_id *lsm_idlist[MAX_LSM_COUNT];
 
 /* Populate ordered LSMs list from comma-separated LSM name list. */
@@ -629,6 +630,8 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
 		lsm_idlist[lsm_active_cnt++] = lsmid;
 		if (lsmid->subjctx)
 			lsm_subjctx_cnt++;
+		if (lsmid->objctx)
+			lsm_objctx_cnt++;
 	}
 
 	for (i = 0; i < count; i++) {
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 1e2e1545eb2e..10b13cd589c5 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -7143,6 +7143,7 @@ static const struct lsm_id selinux_lsmid = {
 	.name = "selinux",
 	.id = LSM_ID_SELINUX,
 	.subjctx = true,
+	.objctx = true,
 };
 
 /*
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 75bd62fe1513..1b42ac32d815 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -5058,6 +5058,7 @@ static const struct lsm_id smack_lsmid = {
 	.name = "smack",
 	.id = LSM_ID_SMACK,
 	.subjctx = true,
+	.objctx = true,
 };
 
 static struct security_hook_list smack_hooks[] __ro_after_init = {
-- 
2.47.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH v2 3/6] LSM: security_lsmblob_to_secctx module selection
  2025-03-07 18:36   ` [PATCH v2 3/6] LSM: security_lsmblob_to_secctx module selection Casey Schaufler
@ 2025-03-08 15:52     ` kernel test robot
  2025-03-12 23:51     ` Paul Moore
  1 sibling, 0 replies; 18+ messages in thread
From: kernel test robot @ 2025-03-08 15:52 UTC (permalink / raw)
  To: Casey Schaufler, paul, eparis, linux-security-module, audit
  Cc: oe-kbuild-all, jmorris, serge, keescook, john.johansen,
	penguin-kernel, stephen.smalley.work, linux-kernel, selinux

Hi Casey,

kernel test robot noticed the following build warnings:

[auto build test WARNING on pcmoore-selinux/next]
[also build test WARNING on linus/master v6.14-rc5 next-20250307]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Casey-Schaufler/Audit-Create-audit_stamp-structure/20250308-024950
base:   https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git next
patch link:    https://lore.kernel.org/r/20250307183701.16970-4-casey%40schaufler-ca.com
patch subject: [PATCH v2 3/6] LSM: security_lsmblob_to_secctx module selection
config: arc-randconfig-001-20250308 (https://download.01.org/0day-ci/archive/20250308/202503082328.C7GyGU63-lkp@intel.com/config)
compiler: arc-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250308/202503082328.C7GyGU63-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202503082328.C7GyGU63-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> security/security.c:4325: warning: Excess function parameter 'lsmid' description in 'security_secid_to_secctx'
>> security/security.c:4344: warning: Function parameter or struct member 'lsmid' not described in 'security_lsmprop_to_secctx'


vim +4325 security/security.c

746df9b59c8a5f1 David Quigley   2013-05-22  4310  
e261301c851aee4 Paul Moore      2023-02-16  4311  /**
e261301c851aee4 Paul Moore      2023-02-16  4312   * security_secid_to_secctx() - Convert a secid to a secctx
e261301c851aee4 Paul Moore      2023-02-16  4313   * @secid: secid
2d470c778120d3c Casey Schaufler 2024-10-23  4314   * @cp: the LSM context
c6b93968f3f6d88 Casey Schaufler 2025-03-07  4315   * @lsmid: which security module to report
e261301c851aee4 Paul Moore      2023-02-16  4316   *
2d470c778120d3c Casey Schaufler 2024-10-23  4317   * Convert secid to security context.  If @cp is NULL the length of the
2d470c778120d3c Casey Schaufler 2024-10-23  4318   * result will be returned, but no data will be returned.  This
e261301c851aee4 Paul Moore      2023-02-16  4319   * does mean that the length could change between calls to check the length and
2d470c778120d3c Casey Schaufler 2024-10-23  4320   * the next call which actually allocates and returns the data.
e261301c851aee4 Paul Moore      2023-02-16  4321   *
2d470c778120d3c Casey Schaufler 2024-10-23  4322   * Return: Return length of data on success, error on failure.
e261301c851aee4 Paul Moore      2023-02-16  4323   */
2d470c778120d3c Casey Schaufler 2024-10-23  4324  int security_secid_to_secctx(u32 secid, struct lsm_context *cp)
20510f2f4e2dabb James Morris    2007-10-16 @4325  {
2d470c778120d3c Casey Schaufler 2024-10-23  4326  	return call_int_hook(secid_to_secctx, secid, cp);
20510f2f4e2dabb James Morris    2007-10-16  4327  }
20510f2f4e2dabb James Morris    2007-10-16  4328  EXPORT_SYMBOL(security_secid_to_secctx);
20510f2f4e2dabb James Morris    2007-10-16  4329  
6f2f724f0e116d9 Casey Schaufler 2024-10-09  4330  /**
6f2f724f0e116d9 Casey Schaufler 2024-10-09  4331   * security_lsmprop_to_secctx() - Convert a lsm_prop to a secctx
6f2f724f0e116d9 Casey Schaufler 2024-10-09  4332   * @prop: lsm specific information
2d470c778120d3c Casey Schaufler 2024-10-23  4333   * @cp: the LSM context
6f2f724f0e116d9 Casey Schaufler 2024-10-09  4334   *
2d470c778120d3c Casey Schaufler 2024-10-23  4335   * Convert a @prop entry to security context.  If @cp is NULL the
2d470c778120d3c Casey Schaufler 2024-10-23  4336   * length of the result will be returned. This does mean that the
2d470c778120d3c Casey Schaufler 2024-10-23  4337   * length could change between calls to check the length and the
2d470c778120d3c Casey Schaufler 2024-10-23  4338   * next call which actually allocates and returns the @cp.
6f2f724f0e116d9 Casey Schaufler 2024-10-09  4339   *
2d470c778120d3c Casey Schaufler 2024-10-23  4340   * Return: Return length of data on success, error on failure.
6f2f724f0e116d9 Casey Schaufler 2024-10-09  4341   */
c6b93968f3f6d88 Casey Schaufler 2025-03-07  4342  int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp,
c6b93968f3f6d88 Casey Schaufler 2025-03-07  4343  			       int lsmid)
6f2f724f0e116d9 Casey Schaufler 2024-10-09 @4344  {
c6b93968f3f6d88 Casey Schaufler 2025-03-07  4345  	struct lsm_static_call *scall;
c6b93968f3f6d88 Casey Schaufler 2025-03-07  4346  
c6b93968f3f6d88 Casey Schaufler 2025-03-07  4347  	lsm_for_each_hook(scall, lsmprop_to_secctx) {
c6b93968f3f6d88 Casey Schaufler 2025-03-07  4348  		if (lsmid != 0 && lsmid != scall->hl->lsmid->id)
c6b93968f3f6d88 Casey Schaufler 2025-03-07  4349  			continue;
c6b93968f3f6d88 Casey Schaufler 2025-03-07  4350  		return scall->hl->hook.lsmprop_to_secctx(prop, cp);
c6b93968f3f6d88 Casey Schaufler 2025-03-07  4351  	}
c6b93968f3f6d88 Casey Schaufler 2025-03-07  4352  	return LSM_RET_DEFAULT(lsmprop_to_secctx);
6f2f724f0e116d9 Casey Schaufler 2024-10-09  4353  }
6f2f724f0e116d9 Casey Schaufler 2024-10-09  4354  EXPORT_SYMBOL(security_lsmprop_to_secctx);
6f2f724f0e116d9 Casey Schaufler 2024-10-09  4355  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2 6/6] Audit: Add record for multiple object contexts
  2025-03-07 18:37   ` [PATCH v2 6/6] Audit: Add record for multiple object contexts Casey Schaufler
@ 2025-03-09 14:18     ` kernel test robot
  2025-03-10  7:26     ` kernel test robot
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 18+ messages in thread
From: kernel test robot @ 2025-03-09 14:18 UTC (permalink / raw)
  To: Casey Schaufler, paul, eparis, linux-security-module, audit
  Cc: llvm, oe-kbuild-all, jmorris, serge, keescook, john.johansen,
	penguin-kernel, stephen.smalley.work, linux-kernel, selinux

Hi Casey,

kernel test robot noticed the following build errors:

[auto build test ERROR on pcmoore-selinux/next]
[also build test ERROR on linus/master v6.14-rc5 next-20250307]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Casey-Schaufler/Audit-Create-audit_stamp-structure/20250308-024950
base:   https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git next
patch link:    https://lore.kernel.org/r/20250307183701.16970-7-casey%40schaufler-ca.com
patch subject: [PATCH v2 6/6] Audit: Add record for multiple object contexts
config: x86_64-kexec (https://download.01.org/0day-ci/archive/20250309/202503092246.du8fixfZ-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250309/202503092246.du8fixfZ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202503092246.du8fixfZ-lkp@intel.com/

All errors (new ones prefixed by >>):

>> ld.lld: error: undefined symbol: lsm_objctx_cnt
   >>> referenced by audit.c:2312 (kernel/audit.c:2312)
   >>>               vmlinux.o:(audit_log_object_context)
--
>> ld.lld: error: undefined symbol: lsm_active_cnt
   >>> referenced by audit.c:2329 (kernel/audit.c:2329)
   >>>               vmlinux.o:(audit_log_object_context)
   >>> referenced by audit.c:2329 (kernel/audit.c:2329)
   >>>               vmlinux.o:(audit_log_object_context)
--
>> ld.lld: error: undefined symbol: lsm_idlist
   >>> referenced by audit.c:2330 (kernel/audit.c:2330)
   >>>               vmlinux.o:(audit_log_object_context)

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2 6/6] Audit: Add record for multiple object contexts
  2025-03-07 18:37   ` [PATCH v2 6/6] Audit: Add record for multiple object contexts Casey Schaufler
  2025-03-09 14:18     ` kernel test robot
@ 2025-03-10  7:26     ` kernel test robot
  2025-03-10  8:20     ` Dan Carpenter
  2025-03-12 23:51     ` Paul Moore
  3 siblings, 0 replies; 18+ messages in thread
From: kernel test robot @ 2025-03-10  7:26 UTC (permalink / raw)
  To: Casey Schaufler, paul, eparis, linux-security-module, audit
  Cc: oe-kbuild-all, jmorris, serge, keescook, john.johansen,
	penguin-kernel, stephen.smalley.work, linux-kernel, selinux

Hi Casey,

kernel test robot noticed the following build errors:

[auto build test ERROR on pcmoore-selinux/next]
[also build test ERROR on linus/master v6.14-rc6 next-20250307]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Casey-Schaufler/Audit-Create-audit_stamp-structure/20250308-024950
base:   https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git next
patch link:    https://lore.kernel.org/r/20250307183701.16970-7-casey%40schaufler-ca.com
patch subject: [PATCH v2 6/6] Audit: Add record for multiple object contexts
config: s390-randconfig-r073-20250310 (https://download.01.org/0day-ci/archive/20250310/202503101524.XYSVbXHw-lkp@intel.com/config)
compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250310/202503101524.XYSVbXHw-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202503101524.XYSVbXHw-lkp@intel.com/

All errors (new ones prefixed by >>):

   s390x-linux-ld: kernel/audit.o: in function `audit_log_object_context':
>> kernel/audit.c:2312:(.text+0x2da6): undefined reference to `lsm_objctx_cnt'
>> s390x-linux-ld: kernel/audit.c:2329:(.text+0x30d2): undefined reference to `lsm_active_cnt'
   s390x-linux-ld: kernel/audit.c:(.text+0x3108): undefined reference to `lsm_active_cnt'
>> s390x-linux-ld: kernel/audit.c:2330:(.text+0x313e): undefined reference to `lsm_idlist'
>> s390x-linux-ld: kernel/audit.c:2312:(.text+0x32f2): undefined reference to `lsm_objctx_cnt'
   s390x-linux-ld: kernel/audit.c:2312:(.text+0x330a): undefined reference to `lsm_objctx_cnt'
   s390x-linux-ld: kernel/audit.c:2329:(.text+0x33a4): undefined reference to `lsm_active_cnt'
   s390x-linux-ld: kernel/audit.c:2329:(.text+0x33bc): undefined reference to `lsm_active_cnt'


vim +2312 kernel/audit.c

  2303	
  2304	int audit_log_object_context(struct audit_buffer *ab, struct lsm_prop *prop)
  2305	{
  2306		int i;
  2307		int rc;
  2308		int error = 0;
  2309		char *space = "";
  2310		struct lsm_context context;
  2311	
> 2312		if (lsm_objctx_cnt < 2) {
  2313			error = security_lsmprop_to_secctx(prop, &context,
  2314							   LSM_ID_UNDEF);
  2315			if (error < 0) {
  2316				if (error != -EINVAL)
  2317					goto error_path;
  2318				return error;
  2319			}
  2320			audit_log_format(ab, " obj=%s", context.context);
  2321			security_release_secctx(&context);
  2322			return 0;
  2323		}
  2324		audit_log_format(ab, " obj=?");
  2325		error = audit_buffer_aux_new(ab, AUDIT_MAC_OBJ_CONTEXTS);
  2326		if (error)
  2327			goto error_path;
  2328	
> 2329		for (i = 0; i < lsm_active_cnt; i++) {
> 2330			if (!lsm_idlist[i]->objctx)
  2331				continue;
  2332			rc = security_lsmprop_to_secctx(prop, &context,
  2333							lsm_idlist[i]->id);
  2334			if (rc < 0) {
  2335				audit_log_format(ab, "%sobj_%s=?", space,
  2336						 lsm_idlist[i]->name);
  2337				if (rc != -EINVAL)
  2338					audit_panic("error in audit_log_object_context");
  2339				error = rc;
  2340			} else {
  2341				audit_log_format(ab, "%sobj_%s=%s", space,
  2342						 lsm_idlist[i]->name, context.context);
  2343				security_release_secctx(&context);
  2344			}
  2345			space = " ";
  2346		}
  2347	
  2348		audit_buffer_aux_end(ab);
  2349		return error;
  2350	
  2351	error_path:
  2352		audit_panic("error in audit_log_object_context");
  2353		return error;
  2354	}
  2355	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2 6/6] Audit: Add record for multiple object contexts
  2025-03-07 18:37   ` [PATCH v2 6/6] Audit: Add record for multiple object contexts Casey Schaufler
  2025-03-09 14:18     ` kernel test robot
  2025-03-10  7:26     ` kernel test robot
@ 2025-03-10  8:20     ` Dan Carpenter
  2025-03-12 23:51     ` Paul Moore
  3 siblings, 0 replies; 18+ messages in thread
From: Dan Carpenter @ 2025-03-10  8:20 UTC (permalink / raw)
  To: oe-kbuild, Casey Schaufler, paul, eparis, linux-security-module,
	audit
  Cc: lkp, oe-kbuild-all, jmorris, serge, keescook, john.johansen,
	penguin-kernel, stephen.smalley.work, linux-kernel, selinux

Hi Casey,

kernel test robot noticed the following build warnings:

https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Casey-Schaufler/Audit-Create-audit_stamp-structure/20250308-024950
base:   https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git next
patch link:    https://lore.kernel.org/r/20250307183701.16970-7-casey%40schaufler-ca.com
patch subject: [PATCH v2 6/6] Audit: Add record for multiple object contexts
config: powerpc64-randconfig-r073-20250309 (https://download.01.org/0day-ci/archive/20250310/202503100802.Dqju4qc5-lkp@intel.com/config)
compiler: powerpc64-linux-gcc (GCC) 14.2.0

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202503100802.Dqju4qc5-lkp@intel.com/

smatch warnings:
kernel/auditsc.c:1753 audit_log_exit() warn: if statement not indented

vim +1753 kernel/auditsc.c

e54dc2431d740a Amy Griffis        2007-03-29  1749  	for (aux = context->aux_pids; aux; aux = aux->next) {
e54dc2431d740a Amy Griffis        2007-03-29  1750  		struct audit_aux_data_pids *axs = (void *)aux;
e54dc2431d740a Amy Griffis        2007-03-29  1751  
e54dc2431d740a Amy Griffis        2007-03-29  1752  		for (i = 0; i < axs->pid_count; i++)
e54dc2431d740a Amy Griffis        2007-03-29 @1753  			if (audit_log_pid_context(context, axs->target_pid[i],
c2a7780efe37d0 Eric Paris         2008-01-07  1754  						  axs->target_auid[i],
c2a7780efe37d0 Eric Paris         2008-01-07  1755  						  axs->target_uid[i],
4746ec5b01ed07 Eric Paris         2008-01-08  1756  						  axs->target_sessionid[i],
13d826e564e2cc Casey Schaufler    2024-10-09  1757  						  &axs->target_ref[i],
c2a7780efe37d0 Eric Paris         2008-01-07  1758  						  axs->target_comm[i]))
e54dc2431d740a Amy Griffis        2007-03-29  1759  			call_panic = 1;

This should be indented another tab.

a5cb013da773a6 Al Viro            2007-03-20  1760  	}
a5cb013da773a6 Al Viro            2007-03-20  1761  
e54dc2431d740a Amy Griffis        2007-03-29  1762  	if (context->target_pid &&
e54dc2431d740a Amy Griffis        2007-03-29  1763  	    audit_log_pid_context(context, context->target_pid,
c2a7780efe37d0 Eric Paris         2008-01-07  1764  				  context->target_auid, context->target_uid,
4746ec5b01ed07 Eric Paris         2008-01-08  1765  				  context->target_sessionid,

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2 1/6] Audit: Create audit_stamp structure
  2025-03-07 18:36   ` [PATCH v2 1/6] Audit: Create audit_stamp structure Casey Schaufler
@ 2025-03-12 23:51     ` Paul Moore
  0 siblings, 0 replies; 18+ messages in thread
From: Paul Moore @ 2025-03-12 23:51 UTC (permalink / raw)
  To: Casey Schaufler, casey, eparis, linux-security-module, audit
  Cc: jmorris, serge, keescook, john.johansen, penguin-kernel,
	stephen.smalley.work, linux-kernel, selinux

On Mar  7, 2025 Casey Schaufler <casey@schaufler-ca.com> wrote:
> 
> Replace the timestamp and serial number pair used in audit records
> with a structure containing the two elements.
> 
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> ---
>  kernel/audit.c   | 17 +++++++++--------
>  kernel/audit.h   | 13 +++++++++----
>  kernel/auditsc.c | 22 +++++++++-------------
>  3 files changed, 27 insertions(+), 25 deletions(-)

...

> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> index 9c853cde9abe..2ec3a0d85447 100644
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -994,10 +994,10 @@ static void audit_reset_context(struct audit_context *ctx)
>  	 */
>  
>  	ctx->current_state = ctx->state;
> -	ctx->serial = 0;
> +	ctx->stamp.serial = 0;
>  	ctx->major = 0;
>  	ctx->uring_op = 0;
> -	ctx->ctime = (struct timespec64){ .tv_sec = 0, .tv_nsec = 0 };
> +	ctx->stamp.ctime = (struct timespec64){ .tv_sec = 0, .tv_nsec = 0 };
>  	memset(ctx->argv, 0, sizeof(ctx->argv));
>  	ctx->return_code = 0;
>  	ctx->prio = (ctx->state == AUDIT_STATE_RECORD ? ~0ULL : 0);

Since we are now combining the timestamp and serial number into a single
struct, let's move both clear/reset instructions together up to where
we currently reset ctx->serial.

--
paul-moore.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2 2/6] Audit: Allow multiple records in an audit_buffer
  2025-03-07 18:36   ` [PATCH v2 2/6] Audit: Allow multiple records in an audit_buffer Casey Schaufler
@ 2025-03-12 23:51     ` Paul Moore
  0 siblings, 0 replies; 18+ messages in thread
From: Paul Moore @ 2025-03-12 23:51 UTC (permalink / raw)
  To: Casey Schaufler, casey, eparis, linux-security-module, audit
  Cc: jmorris, serge, keescook, john.johansen, penguin-kernel,
	stephen.smalley.work, linux-kernel, selinux

On Mar  7, 2025 Casey Schaufler <casey@schaufler-ca.com> wrote:
> 
> Replace the single skb pointer in an audit_buffer with
> a list of skb pointers. Add the audit_stamp information
> to the audit_buffer as there's no guarantee that there
> will be an audit_context containing the stamp associated
> with the event. At audit_log_end() time create auxiliary
> records (none are currently defined) as have been added
> to the list. Functions are created to manage the skb list
> in the audit_buffer.
> 
> Suggested-by: Paul Moore <paul@paul-moore.com>
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> ---
>  kernel/audit.c | 111 +++++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 89 insertions(+), 22 deletions(-)

This may need to be squashed with a later patch as I get
"defined but not used" warnings/errors for audit_buffer_aux_{new,end}().

> diff --git a/kernel/audit.c b/kernel/audit.c
> index 2a567f667528..a4945f1c3ec0 100644
> --- a/kernel/audit.c
> +++ b/kernel/audit.c
> @@ -2412,26 +2471,14 @@ int audit_signal_info(int sig, struct task_struct *t)
>  }
>  
>  /**
> - * audit_log_end - end one audit record
> - * @ab: the audit_buffer
> - *
> - * We can not do a netlink send inside an irq context because it blocks (last
> - * arg, flags, is not set to MSG_DONTWAIT), so the audit buffer is placed on a
> - * queue and a kthread is scheduled to remove them from the queue outside the
> - * irq context.  May be called in any context.
> + * __audit_log_end - enqueue one audit record
> + * @skb: the buffer to send
>   */
> -void audit_log_end(struct audit_buffer *ab)
> +static void __audit_log_end(struct sk_buff *skb)
>  {
> -	struct sk_buff *skb;
>  	struct nlmsghdr *nlh;
>  
> -	if (!ab)
> -		return;
> -
>  	if (audit_rate_check()) {
> -		skb = ab->skb;
> -		ab->skb = NULL;
> -
>  		/* setup the netlink header, see the comments in
>  		 * kauditd_send_multicast_skb() for length quirks */
>  		nlh = nlmsg_hdr(skb);
> @@ -2442,6 +2489,26 @@ void audit_log_end(struct audit_buffer *ab)
>  		wake_up_interruptible(&kauditd_wait);

We should probably move the kauditd thread wake into audit_log_end()
so we don't end up poking the scheduler multiple times.

>  	} else
>  		audit_log_lost("rate limit exceeded");
> +}
> +
> +/**
> + * audit_log_end - end one audit record
> + * @ab: the audit_buffer
> + *
> + * We can not do a netlink send inside an irq context because it blocks (last
> + * arg, flags, is not set to MSG_DONTWAIT), so the audit buffer is placed on a
> + * queue and a kthread is scheduled to remove them from the queue outside the
> + * irq context.  May be called in any context.
> + */
> +void audit_log_end(struct audit_buffer *ab)
> +{
> +	struct sk_buff *skb;
> +
> +	if (!ab)
> +		return;
> +
> +	while ((skb = skb_dequeue(&ab->skb_list)))
> +		__audit_log_end(skb);

Put the kauditd thread wake here.

>  	audit_buffer_free(ab);
>  }
> -- 
> 2.47.0

--
paul-moore.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2 3/6] LSM: security_lsmblob_to_secctx module selection
  2025-03-07 18:36   ` [PATCH v2 3/6] LSM: security_lsmblob_to_secctx module selection Casey Schaufler
  2025-03-08 15:52     ` kernel test robot
@ 2025-03-12 23:51     ` Paul Moore
  1 sibling, 0 replies; 18+ messages in thread
From: Paul Moore @ 2025-03-12 23:51 UTC (permalink / raw)
  To: Casey Schaufler, casey, eparis, linux-security-module, audit
  Cc: jmorris, serge, keescook, john.johansen, penguin-kernel,
	stephen.smalley.work, linux-kernel, selinux

On Mar  7, 2025 Casey Schaufler <casey@schaufler-ca.com> wrote:
> 
> 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>
> ---
>  include/linux/security.h     |  6 ++++--
>  kernel/audit.c               |  4 ++--
>  kernel/auditsc.c             |  8 +++++---
>  net/netlabel/netlabel_user.c |  3 ++-
>  security/security.c          | 13 +++++++++++--
>  5 files changed, 24 insertions(+), 10 deletions(-)

...

> diff --git a/security/security.c b/security/security.c
> index 143561ebc3e8..55f9c7ad3f89 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -4338,9 +4339,17 @@ EXPORT_SYMBOL(security_secid_to_secctx);
>   *
>   * 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 != 0 && lsmid != scall->hl->lsmid->id)

Let's use LSM_ID_UNDEF instead of 0 here to add some clarity on how an
undefined ID is handled.  The function header comment should also
explain the special handling when LSM_ID_UNDEF is specified.

--
paul-moore.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2 4/6] Audit: Add record for multiple task security  contexts
  2025-03-07 18:36   ` [PATCH v2 4/6] Audit: Add record for multiple task security contexts Casey Schaufler
@ 2025-03-12 23:51     ` Paul Moore
  2025-03-13 12:29       ` Paul Moore
  0 siblings, 1 reply; 18+ messages in thread
From: Paul Moore @ 2025-03-12 23:51 UTC (permalink / raw)
  To: Casey Schaufler, casey, eparis, linux-security-module, audit
  Cc: jmorris, serge, keescook, john.johansen, penguin-kernel,
	stephen.smalley.work, linux-kernel, selinux

On Mar  7, 2025 Casey Schaufler <casey@schaufler-ca.com> wrote:
> 
> Create a new audit record AUDIT_MAC_TASK_CONTEXTS.
> An example of the MAC_TASK_CONTEXTS (1423) record is:
> 
>     type=MAC_TASK_CONTEXTS[1423]
>     msg=audit(1600880931.832:113)
>     subj_apparmor=unconfined
>     subj_smack=_
> 
> When an audit event includes a AUDIT_MAC_TASK_CONTEXTS record
> the "subj=" field in other records in the event will be "subj=?".
> An AUDIT_MAC_TASK_CONTEXTS record is supplied when the system has
> multiple security modules that may make access decisions based
> on a subject security context.
> 
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> ---
>  include/linux/lsm_hooks.h  |  1 +
>  include/linux/security.h   |  1 +
>  include/uapi/linux/audit.h |  1 +
>  kernel/audit.c             | 45 ++++++++++++++++++++++++++++++++------
>  security/apparmor/lsm.c    |  1 +
>  security/bpf/hooks.c       |  1 +
>  security/security.c        |  3 +++
>  security/selinux/hooks.c   |  1 +
>  security/smack/smack_lsm.c |  1 +
>  9 files changed, 48 insertions(+), 7 deletions(-)
> 
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 090d1d3e19fe..e4d303ab1f20 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -81,6 +81,7 @@ struct lsm_static_calls_table {
>  struct lsm_id {
>  	const char *name;
>  	u64 id;
> +	bool subjctx;
>  };

The new field needs to be documented in the comment block for the
struct, and while I'll reserve judgement until I see the description,
I believe this field either needs to be renamed, moved elsewhere, or
simply "disappeared" in favor of something else.

> diff --git a/include/linux/security.h b/include/linux/security.h
> index 540894695c4b..79a9bf4a7cdd 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -168,6 +168,7 @@ struct lsm_prop {
>  
>  extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1];
>  extern u32 lsm_active_cnt;
> +extern u32 lsm_subjctx_cnt;

I'm not loving this.  More below, but I'd really like to hide some of
this detail inside a LSM API/hook if possible.

>  extern const struct lsm_id *lsm_idlist[];
>  
>  /* These functions are in security/commoncap.c */
> diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
> index d9a069b4a775..5ebb5d80363d 100644
> --- a/include/uapi/linux/audit.h
> +++ b/include/uapi/linux/audit.h
> @@ -146,6 +146,7 @@
>  #define AUDIT_IPE_ACCESS	1420	/* IPE denial or grant */
>  #define AUDIT_IPE_CONFIG_CHANGE	1421	/* IPE config change */
>  #define AUDIT_IPE_POLICY_LOAD	1422	/* IPE policy load */
> +#define AUDIT_MAC_TASK_CONTEXTS	1423	/* Multiple LSM task contexts */
>  
>  #define AUDIT_FIRST_KERN_ANOM_MSG   1700
>  #define AUDIT_LAST_KERN_ANOM_MSG    1799
> diff --git a/kernel/audit.c b/kernel/audit.c
> index 293364bba961..59eaf69ee8ac 100644
> --- a/kernel/audit.c
> +++ b/kernel/audit.c
> @@ -54,6 +54,7 @@
>  #include <net/netlink.h>
>  #include <linux/skbuff.h>
>  #include <linux/security.h>
> +#include <linux/lsm_hooks.h>
>  #include <linux/freezer.h>
>  #include <linux/pid_namespace.h>
>  #include <net/netns/generic.h>
> @@ -2241,21 +2242,51 @@ int audit_log_task_context(struct audit_buffer *ab)
>  {
>  	struct lsm_prop prop;
>  	struct lsm_context ctx;
> +	bool space = false;
>  	int error;
> +	int i;
>  
>  	security_current_getlsmprop_subj(&prop);
>  	if (!lsmprop_is_set(&prop))
>  		return 0;
>  
> -	error = security_lsmprop_to_secctx(&prop, &ctx, LSM_ID_UNDEF);
> -	if (error < 0) {
> -		if (error != -EINVAL)
> -			goto error_path;
> +	if (lsm_subjctx_cnt < 2) {
> +		error = security_lsmprop_to_secctx(&prop, &ctx, LSM_ID_UNDEF);
> +		if (error < 0) {
> +			if (error != -EINVAL)
> +				goto error_path;
> +			return 0;
> +		}
> +		audit_log_format(ab, " subj=%s", ctx.context);
> +		security_release_secctx(&ctx);
>  		return 0;
>  	}
> -
> -	audit_log_format(ab, " subj=%s", ctx.context);
> -	security_release_secctx(&ctx);
> +	/* Multiple LSMs provide contexts. Include an aux record. */
> +	audit_log_format(ab, " subj=?");
> +	error = audit_buffer_aux_new(ab, AUDIT_MAC_TASK_CONTEXTS);
> +	if (error)
> +		goto error_path;
> +
> +	for (i = 0; i < lsm_active_cnt; i++) {
> +		if (!lsm_idlist[i]->subjctx)
> +			continue;
> +		error = security_lsmprop_to_secctx(&prop, &ctx,
> +						   lsm_idlist[i]->id);
> +		if (error < 0) {
> +			if (error == -EOPNOTSUPP)
> +				continue;
> +			audit_log_format(ab, "%ssubj_%s=?", space ? " " : "",
> +					 lsm_idlist[i]->name);
> +			if (error != -EINVAL)
> +				audit_panic("error in audit_log_task_context");
> +		} else {
> +			audit_log_format(ab, "%ssubj_%s=%s", space ? " " : "",
> +					 lsm_idlist[i]->name, ctx.context);
> +			security_release_secctx(&ctx);
> +		}
> +		space = true;
> +	}
> +	audit_buffer_aux_end(ab);
>  	return 0;

I'd really like to see us develop something a bit cleaner than the
code above.  It looks like there are two things that we're currently
missing in the LSM API: a count of the number of LSMs supplying data
in a lsm_prop struct, and a mechanism to iterate through a lsm_prop
and act on each LSM's data.

As far as the count is concerned, I think we can take a similar
approach to what we do with MAX_LSM_COUNT to generate a value at
build time, for example (pardon the lazy pseudo code):

 >>> include/linux/lsm_count.h
 
#if IS_ENABLED(CONFIG_SECURITY_SMACK)
#define SMACK_ENABLED 1,
#define SMACK_LSMPROP 1,
#else
#define SMACK_ENABLED
#define SMACK_LSMPROP
#endif

#define MAX_LSM_PROPS \
  COUNT_LSMS(         \
    SMACK_LSMPROP     \
    ...)              \

The iterator mechanism is a little more complex, but I think the
interface and resulting will be a lot cleaner, at least to in my mind.

 >>> LSM hook

int security_lsmprop_walk(void *data,
                          void (*iter)(struct lsm_id *lsm, void *data,
                                      char *secctx, u32 secid));

 >>> example audit code

struct lsmprop_walk_data {
  struct audit_buffer *ab;
  unsigned int count;
};

void audit_lsmprop_walk(struct lsm_id *lsm, void *data,
                        char *secctx, u32 secid)
{
  struct lsmprop_walk_data *walk = data;

  audit_log_format(data->ab, "%ssubj_%s=%s",
                   (data->count++ ? " " : ""),
                   lsm->name, (secctx ? secctx : "?"));
  if (secctx)
    security_release_secctx(secctx);
}

int audit_log_task_context(...)
{
  ...

  if (MAX_LSM_PROPS <= 1) {
    security_lsmprop_to_secctx(...)
    audit_log_format(...);
  } else {
    struct lsmprop_walk_data data = { .ab = ab, count = 0 };

    audit_buffer_aux_new(ab, AUDIT_MAC_TASK_CONTEXTS);
    security_lsmprop_walk(data, audit_lsmprop_walk);
    audit_buffer_aux_end(
  }
  
  ...
}

--
paul-moore.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2 5/6] Audit: multiple subject lsm values for netlabel
  2025-03-07 18:37   ` [PATCH v2 5/6] Audit: multiple subject lsm values for netlabel Casey Schaufler
@ 2025-03-12 23:51     ` Paul Moore
  0 siblings, 0 replies; 18+ messages in thread
From: Paul Moore @ 2025-03-12 23:51 UTC (permalink / raw)
  To: Casey Schaufler, casey, eparis, linux-security-module, audit
  Cc: jmorris, serge, keescook, john.johansen, penguin-kernel,
	stephen.smalley.work, linux-kernel, selinux

On Mar  7, 2025 Casey Schaufler <casey@schaufler-ca.com> wrote:
> 
> Refactor audit_log_task_context(), creating a new
> audit_log_subject_context(). This is used in netlabel auditing
> to provide multiple subject security contexts as necessary.
> 
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> ---
>  include/linux/audit.h        |  8 ++++++++
>  kernel/audit.c               | 21 ++++++++++++++-------
>  net/netlabel/netlabel_user.c |  9 +--------
>  3 files changed, 23 insertions(+), 15 deletions(-)
> 
> diff --git a/include/linux/audit.h b/include/linux/audit.h
> index 0050ef288ab3..ee3e2ce70c45 100644
> --- a/include/linux/audit.h
> +++ b/include/linux/audit.h
> @@ -37,6 +37,7 @@ struct audit_watch;
>  struct audit_tree;
>  struct sk_buff;
>  struct kern_ipc_perm;
> +struct lsm_prop;
>  
>  struct audit_krule {
>  	u32			pflags;
> @@ -185,6 +186,8 @@ extern void		    audit_log_path_denied(int type,
>  						  const char *operation);
>  extern void		    audit_log_lost(const char *message);
>  
> +extern int audit_log_subject_context(struct audit_buffer *ab,
> +				     struct lsm_prop *blob);

Let's try to keep the typing down, how about "audit_log_subj_ctx()"?

--
paul-moore.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2 6/6] Audit: Add record for multiple object contexts
  2025-03-07 18:37   ` [PATCH v2 6/6] Audit: Add record for multiple object contexts Casey Schaufler
                       ` (2 preceding siblings ...)
  2025-03-10  8:20     ` Dan Carpenter
@ 2025-03-12 23:51     ` Paul Moore
  3 siblings, 0 replies; 18+ messages in thread
From: Paul Moore @ 2025-03-12 23:51 UTC (permalink / raw)
  To: Casey Schaufler, casey, eparis, linux-security-module, audit
  Cc: jmorris, serge, keescook, john.johansen, penguin-kernel,
	stephen.smalley.work, linux-kernel, selinux

On Mar  7, 2025 Casey Schaufler <casey@schaufler-ca.com> wrote:
> 
> Create a new audit record AUDIT_MAC_OBJ_CONTEXTS.
> An example of the MAC_OBJ_CONTEXTS (1424) record is:
> 
>     type=MAC_OBJ_CONTEXTS[1424]
>     msg=audit(1601152467.009:1050):
>     obj_selinux=unconfined_u:object_r:user_home_t:s0
> 
> When an audit event includes a AUDIT_MAC_OBJ_CONTEXTS record
> the "obj=" field in other records in the event will be "obj=?".
> An AUDIT_MAC_OBJ_CONTEXTS record is supplied when the system has
> multiple security modules that may make access decisions based
> on an object security context.
> 
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> ---
>  include/linux/audit.h      |  7 ++++-
>  include/linux/lsm_hooks.h  |  3 +++
>  include/linux/security.h   |  1 +
>  include/uapi/linux/audit.h |  1 +
>  kernel/audit.c             | 53 +++++++++++++++++++++++++++++++++++++-
>  kernel/auditsc.c           | 45 ++++++++------------------------
>  security/security.c        |  3 +++
>  security/selinux/hooks.c   |  1 +
>  security/smack/smack_lsm.c |  1 +
>  9 files changed, 79 insertions(+), 36 deletions(-)
> 
> diff --git a/include/linux/audit.h b/include/linux/audit.h
> index ee3e2ce70c45..0b17acf459f2 100644
> --- a/include/linux/audit.h
> +++ b/include/linux/audit.h
> @@ -186,8 +186,10 @@ extern void		    audit_log_path_denied(int type,
>  						  const char *operation);
>  extern void		    audit_log_lost(const char *message);
>  
> +extern int audit_log_object_context(struct audit_buffer *ab,
> +				    struct lsm_prop *prop);

Less is more, "audit_log_obj_ctx()" to match "audit_log_subj_ctx()".

>  extern int audit_log_subject_context(struct audit_buffer *ab,
> -				     struct lsm_prop *blob);
> +				     struct lsm_prop *prop);

Do that back in patch 5/6 please.

> diff --git a/kernel/audit.c b/kernel/audit.c
> index f0c1f0c0b250..054776f29327 100644
> --- a/kernel/audit.c
> +++ b/kernel/audit.c
> @@ -1116,7 +1116,6 @@ static int is_audit_feature_set(int i)
>  	return af.features & AUDIT_FEATURE_TO_MASK(i);
>  }
>  
> -
>  static int audit_get_feature(struct sk_buff *skb)
>  {
>  	u32 seq;
> @@ -2302,6 +2301,58 @@ int audit_log_task_context(struct audit_buffer *ab)
>  }
>  EXPORT_SYMBOL(audit_log_task_context);
>  
> +int audit_log_object_context(struct audit_buffer *ab, struct lsm_prop *prop)
> +{
> +	int i;
> +	int rc;
> +	int error = 0;
> +	char *space = "";
> +	struct lsm_context context;
> +
> +	if (lsm_objctx_cnt < 2) {
> +		error = security_lsmprop_to_secctx(prop, &context,
> +						   LSM_ID_UNDEF);
> +		if (error < 0) {
> +			if (error != -EINVAL)
> +				goto error_path;
> +			return error;
> +		}
> +		audit_log_format(ab, " obj=%s", context.context);
> +		security_release_secctx(&context);
> +		return 0;
> +	}
> +	audit_log_format(ab, " obj=?");
> +	error = audit_buffer_aux_new(ab, AUDIT_MAC_OBJ_CONTEXTS);
> +	if (error)
> +		goto error_path;
> +
> +	for (i = 0; i < lsm_active_cnt; i++) {
> +		if (!lsm_idlist[i]->objctx)
> +			continue;
> +		rc = security_lsmprop_to_secctx(prop, &context,
> +						lsm_idlist[i]->id);
> +		if (rc < 0) {
> +			audit_log_format(ab, "%sobj_%s=?", space,
> +					 lsm_idlist[i]->name);
> +			if (rc != -EINVAL)
> +				audit_panic("error in audit_log_object_context");
> +			error = rc;
> +		} else {
> +			audit_log_format(ab, "%sobj_%s=%s", space,
> +					 lsm_idlist[i]->name, context.context);
> +			security_release_secctx(&context);
> +		}
> +		space = " ";
> +	}
> +
> +	audit_buffer_aux_end(ab);
> +	return error;
> +
> +error_path:
> +	audit_panic("error in audit_log_object_context");
> +	return error;
> +}

Let's follow the same code pattern as suggested for the subject.

> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> index d98ce7097a2d..82470862ea81 100644
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -1780,15 +1756,16 @@ static void audit_log_exit(void)
>  						  axs->target_sessionid[i],
>  						  &axs->target_ref[i],
>  						  axs->target_comm[i]))
> -				call_panic = 1;
> +			call_panic = 1;
>  	}
>  
>  	if (context->target_pid &&
>  	    audit_log_pid_context(context, context->target_pid,
>  				  context->target_auid, context->target_uid,
>  				  context->target_sessionid,
> -				  &context->target_ref, context->target_comm))
> -			call_panic = 1;
> +				  &context->target_ref,
> +				  context->target_comm))
> +		call_panic = 1;

Thank you for both of the indent fixes above.

--
paul-moore.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2 4/6] Audit: Add record for multiple task security contexts
  2025-03-12 23:51     ` Paul Moore
@ 2025-03-13 12:29       ` Paul Moore
  0 siblings, 0 replies; 18+ messages in thread
From: Paul Moore @ 2025-03-13 12:29 UTC (permalink / raw)
  To: Casey Schaufler, eparis, linux-security-module, audit
  Cc: jmorris, serge, keescook, john.johansen, penguin-kernel,
	stephen.smalley.work, linux-kernel, selinux


On March 12, 2025 7:51:36 PM Paul Moore <paul@paul-moore.com> wrote:
> On Mar  7, 2025 Casey Schaufler <casey@schaufler-ca.com> wrote:

...

>
>> diff --git a/include/linux/security.h b/include/linux/security.h
>> index 540894695c4b..79a9bf4a7cdd 100644
>> --- a/include/linux/security.h
>> +++ b/include/linux/security.h
>> @@ -168,6 +168,7 @@ struct lsm_prop {
>>
>> extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1];
>> extern u32 lsm_active_cnt;
>> +extern u32 lsm_subjctx_cnt;
>
> I'm not loving this.  More below, but I'd really like to hide some of
> this detail inside a LSM API/hook if possible.

Thinking more about this I think we can't go with a LSM_MAX_PROPS, or 
similar determined at build time since we have the ability to toggle LSMs 
at boot.  Need to think on this some more, but the answer is going to have 
to be a variable and not a #define.

The LSM init work I'm doing right now directly impacts this, and I'm in the 
final stages now. Let me see what looks reasonable and I'll get back to you.

--
paul-moore.com
>



^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2025-03-13 12:29 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20250307183701.16970-1-casey.ref@schaufler-ca.com>
2025-03-07 18:36 ` [PATCH v2 0/6] Audit: Records for multiple security contexts Casey Schaufler
2025-03-07 18:36   ` [PATCH v2 1/6] Audit: Create audit_stamp structure Casey Schaufler
2025-03-12 23:51     ` Paul Moore
2025-03-07 18:36   ` [PATCH v2 2/6] Audit: Allow multiple records in an audit_buffer Casey Schaufler
2025-03-12 23:51     ` Paul Moore
2025-03-07 18:36   ` [PATCH v2 3/6] LSM: security_lsmblob_to_secctx module selection Casey Schaufler
2025-03-08 15:52     ` kernel test robot
2025-03-12 23:51     ` Paul Moore
2025-03-07 18:36   ` [PATCH v2 4/6] Audit: Add record for multiple task security contexts Casey Schaufler
2025-03-12 23:51     ` Paul Moore
2025-03-13 12:29       ` Paul Moore
2025-03-07 18:37   ` [PATCH v2 5/6] Audit: multiple subject lsm values for netlabel Casey Schaufler
2025-03-12 23:51     ` Paul Moore
2025-03-07 18:37   ` [PATCH v2 6/6] Audit: Add record for multiple object contexts Casey Schaufler
2025-03-09 14:18     ` kernel test robot
2025-03-10  7:26     ` kernel test robot
2025-03-10  8:20     ` Dan Carpenter
2025-03-12 23:51     ` Paul Moore

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).