Replace the secid value stored in struct audit_context with a struct
lsmblob. Change the code that uses this value to accommodate the
change. security_audit_rule_match() expects a lsmblob, so existing
scaffolding can be removed. A call to security_secid_to_secctx()
is changed to security_lsmblob_to_secctx(). The call to
security_ipc_getsecid() is scaffolded.
A new function lsmblob_is_set() is introduced to identify whether
an lsmblob contains a non-zero value.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/security.h | 13 +++++++++++++
kernel/audit.h | 3 ++-
kernel/auditsc.c | 19 ++++++++-----------
3 files changed, 23 insertions(+), 12 deletions(-)
diff --git a/include/linux/security.h b/include/linux/security.h
index 457fafc32fb0..a0b23b6e8734 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -277,6 +277,19 @@ static inline const char *kernel_load_data_id_str(enum kernel_load_data_id id)
return kernel_load_data_str[id];
}
+/**
+ * lsmblob_is_set - report if there is a value in the lsmblob
+ * @blob: Pointer to the exported LSM data
+ *
+ * Returns true if there is a value set, false otherwise
+ */
+static inline bool lsmblob_is_set(struct lsmblob *blob)
+{
+ const struct lsmblob empty = {};
+
+ return !!memcmp(blob, &empty, sizeof(*blob));
+}
+
#ifdef CONFIG_SECURITY
int call_blocking_lsm_notifier(enum lsm_event event, void *data);
diff --git a/kernel/audit.h b/kernel/audit.h
index a60d2840559e..b1f2de4d4f1e 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -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 lsmblob oblob;
int has_perm;
uid_t perm_uid;
gid_t perm_gid;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 23adb15cae43..84f6e9356b8f 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -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 */
- blob.scaffold.secid = ctx->ipc.osid;
- if (security_audit_rule_match(&blob,
+ if (security_audit_rule_match(&ctx->ipc.oblob,
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 (lsmblob_is_set(&context->ipc.oblob)) {
char *ctx = NULL;
u32 len;
- if (security_secid_to_secctx(osid, &ctx, &len)) {
- audit_log_format(ab, " osid=%u", osid);
+ if (security_lsmblob_to_secctx(&context->ipc.oblob,
+ &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.oblob.scaffold.secid);
context->type = AUDIT_IPC;
}
--
2.41.0
On Sun, 2024-08-25 at 12:00 -0700, Casey Schaufler wrote:
> Replace the secid value stored in struct audit_context with a struct
> lsmblob. Change the code that uses this value to accommodate the
> change. security_audit_rule_match() expects a lsmblob, so existing
> scaffolding can be removed. A call to security_secid_to_secctx()
> is changed to security_lsmblob_to_secctx(). The call to
> security_ipc_getsecid() is scaffolded.
>
> A new function lsmblob_is_set() is introduced to identify whether
> an lsmblob contains a non-zero value.
>
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> ---
> include/linux/security.h | 13 +++++++++++++
> kernel/audit.h | 3 ++-
> kernel/auditsc.c | 19 ++++++++-----------
> 3 files changed, 23 insertions(+), 12 deletions(-)
>
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 457fafc32fb0..a0b23b6e8734 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -277,6 +277,19 @@ static inline const char *kernel_load_data_id_str(enum kernel_load_data_id id)
> return kernel_load_data_str[id];
> }
>
> +/**
> + * lsmblob_is_set - report if there is a value in the lsmblob
> + * @blob: Pointer to the exported LSM data
> + *
> + * Returns true if there is a value set, false otherwise
> + */
> +static inline bool lsmblob_is_set(struct lsmblob *blob)
> +{
> + const struct lsmblob empty = {};
> +
> + return !!memcmp(blob, &empty, sizeof(*blob));
> +}
> +
> #ifdef CONFIG_SECURITY
>
> int call_blocking_lsm_notifier(enum lsm_event event, void *data);
> diff --git a/kernel/audit.h b/kernel/audit.h
> index a60d2840559e..b1f2de4d4f1e 100644
> --- a/kernel/audit.h
> +++ b/kernel/audit.h
> @@ -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 lsmblob oblob;
> int has_perm;
> uid_t perm_uid;
> gid_t perm_gid;
> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> index 23adb15cae43..84f6e9356b8f 100644
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -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 */
> - blob.scaffold.secid = ctx->ipc.osid;
> - if (security_audit_rule_match(&blob,
> + if (security_audit_rule_match(&ctx->ipc.oblob,
> 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 (lsmblob_is_set(&context->ipc.oblob)) {
> char *ctx = NULL;
> u32 len;
>
> - if (security_secid_to_secctx(osid, &ctx, &len)) {
> - audit_log_format(ab, " osid=%u", osid);
> + if (security_lsmblob_to_secctx(&context->ipc.oblob,
> + &ctx, &len)) {
Is there any reason to stop auditing secid when we fail to get the
security context?
> *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.oblob.scaffold.secid);
> context->type = AUDIT_IPC;
> }
>
On Tue, 2024-08-27 at 12:01 -0300, Georgia Garcia wrote:
> On Sun, 2024-08-25 at 12:00 -0700, Casey Schaufler wrote:
> > Replace the secid value stored in struct audit_context with a struct
> > lsmblob. Change the code that uses this value to accommodate the
> > change. security_audit_rule_match() expects a lsmblob, so existing
> > scaffolding can be removed. A call to security_secid_to_secctx()
> > is changed to security_lsmblob_to_secctx(). The call to
> > security_ipc_getsecid() is scaffolded.
> >
> > A new function lsmblob_is_set() is introduced to identify whether
> > an lsmblob contains a non-zero value.
> >
> > Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> > ---
> > include/linux/security.h | 13 +++++++++++++
> > kernel/audit.h | 3 ++-
> > kernel/auditsc.c | 19 ++++++++-----------
> > 3 files changed, 23 insertions(+), 12 deletions(-)
> >
> > diff --git a/include/linux/security.h b/include/linux/security.h
> > index 457fafc32fb0..a0b23b6e8734 100644
> > --- a/include/linux/security.h
> > +++ b/include/linux/security.h
> > @@ -277,6 +277,19 @@ static inline const char *kernel_load_data_id_str(enum kernel_load_data_id id)
> > return kernel_load_data_str[id];
> > }
> >
> > +/**
> > + * lsmblob_is_set - report if there is a value in the lsmblob
> > + * @blob: Pointer to the exported LSM data
> > + *
> > + * Returns true if there is a value set, false otherwise
> > + */
> > +static inline bool lsmblob_is_set(struct lsmblob *blob)
> > +{
> > + const struct lsmblob empty = {};
> > +
> > + return !!memcmp(blob, &empty, sizeof(*blob));
> > +}
> > +
> > #ifdef CONFIG_SECURITY
> >
> > int call_blocking_lsm_notifier(enum lsm_event event, void *data);
> > diff --git a/kernel/audit.h b/kernel/audit.h
> > index a60d2840559e..b1f2de4d4f1e 100644
> > --- a/kernel/audit.h
> > +++ b/kernel/audit.h
> > @@ -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 lsmblob oblob;
> > int has_perm;
> > uid_t perm_uid;
> > gid_t perm_gid;
> > diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> > index 23adb15cae43..84f6e9356b8f 100644
> > --- a/kernel/auditsc.c
> > +++ b/kernel/auditsc.c
> > @@ -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 */
> > - blob.scaffold.secid = ctx->ipc.osid;
> > - if (security_audit_rule_match(&blob,
> > + if (security_audit_rule_match(&ctx->ipc.oblob,
> > 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 (lsmblob_is_set(&context->ipc.oblob)) {
> > char *ctx = NULL;
> > u32 len;
> >
> > - if (security_secid_to_secctx(osid, &ctx, &len)) {
> > - audit_log_format(ab, " osid=%u", osid);
> > + if (security_lsmblob_to_secctx(&context->ipc.oblob,
> > + &ctx, &len)) {
>
> Is there any reason to stop auditing secid when we fail to get the
> security context?
Well, yes, if we're moving away from using secid for all LSMs, then it
doesn't make sense to audit it here anymore, so nevermind :)
>
> > *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.oblob.scaffold.secid);
> > context->type = AUDIT_IPC;
> > }
> >
>
© 2016 - 2025 Red Hat, Inc.