* [RFC PATCH 1/4] audit: separate file and process capability storage
@ 2026-09-17 14:39 Christian Göttsche
2026-09-17 14:39 ` [RFC PATCH 2/4] audit: compact name entries and context fields Christian Göttsche
` (4 more replies)
0 siblings, 5 replies; 12+ messages in thread
From: Christian Göttsche @ 2026-09-17 14:39 UTC (permalink / raw)
To: audit; +Cc: Paul Moore, Eric Paris, Christian Göttsche
From: Christian Göttsche <cgzones@googlemail.com>
File capabilities need permitted and inheritable sets, an effective flag,
and a root UID. Process capabilities need four full capability sets but
neither a file effective flag nor a root UID. Give file capabilities their
own type instead of storing both representations in audit_cap_data.
This reduces each preallocated audit_names entry by 16 bytes on the tested
64-bit configurations, saving 80 bytes per audit context. The BPRM
capability auxiliary object also shrinks from 144 to 112 bytes. Retain all
logged fields, including file root IDs and process ambient capabilities;
record formats and collection behavior are unchanged.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
kernel/audit.h | 15 +++++++++------
kernel/auditsc.c | 2 +-
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/kernel/audit.h b/kernel/audit.h
index 3176da464843..7640d2c0fba4 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -53,15 +53,18 @@ struct audit_entry {
struct audit_krule rule;
};
+struct audit_file_caps {
+ kernel_cap_t permitted;
+ kernel_cap_t inheritable;
+ unsigned int fE; /* effective bit of file cap */
+ kuid_t rootid;
+};
+
struct audit_cap_data {
kernel_cap_t permitted;
kernel_cap_t inheritable;
- union {
- unsigned int fE; /* effective bit of file cap */
- kernel_cap_t effective; /* effective set of process */
- };
+ kernel_cap_t effective;
kernel_cap_t ambient;
- kuid_t rootid;
};
/* When fs/namei.c:getname() is called, we store the pointer in name and bump
@@ -83,7 +86,7 @@ struct audit_names {
kgid_t gid;
dev_t rdev;
struct lsm_prop oprop;
- struct audit_cap_data fcap;
+ struct audit_file_caps fcap;
unsigned int fcap_ver;
unsigned char type; /* record type */
/*
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index ee7e53d2cd52..464736499c83 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -107,7 +107,7 @@ struct audit_aux_data_pids {
struct audit_aux_data_bprm_fcaps {
struct audit_aux_data d;
- struct audit_cap_data fcap;
+ struct audit_file_caps fcap;
unsigned int fcap_ver;
struct audit_cap_data old_pcap;
struct audit_cap_data new_pcap;
--
2.55.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [RFC PATCH 2/4] audit: compact name entries and context fields
2026-09-17 14:39 [RFC PATCH 1/4] audit: separate file and process capability storage Christian Göttsche
@ 2026-09-17 14:39 ` Christian Göttsche
2026-09-17 14:49 ` sashiko-bot
2026-09-28 22:10 ` [PATCH RFC " Paul Moore
2026-09-17 14:39 ` [RFC PATCH 3/4] audit: return the collected inode entry from a private helper Christian Göttsche
` (3 subsequent siblings)
4 siblings, 2 replies; 12+ messages in thread
From: Christian Göttsche @ 2026-09-17 14:39 UTC (permalink / raw)
To: audit; +Cc: Paul Moore, Eric Paris, Christian Göttsche
From: Christian Göttsche <cgzones@googlemail.com>
Group aligned name fields and small scalar fields to remove padding. Keep
file capabilities last so they do not separate inode and pathname metadata.
Store the per-name file capability revision in s16: it must represent both
the eight-bit on-disk revision and the -1 AUDIT_INODE_NOEVAL sentinel. Keep
the existing formatter and its unknown-capability output unchanged.
Move name_count beside return_valid to remove two alignment holes, and
place personality before the task credential scalars. Preserve the first
int dummy member required by audit_dummy_context(), all five embedded name
slots, and the existing allocation and reference lifetimes.
On x86_64 with SELinux this reduces audit_context from 928 to 880 bytes,
leaving room for descriptor paths while staying below 1 KiB. On the tested
arm64 configuration without property-bearing LSMs it falls to 872 bytes.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
kernel/audit.h | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/kernel/audit.h b/kernel/audit.h
index 7640d2c0fba4..bd798f8553a0 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -76,18 +76,16 @@ struct audit_names {
struct list_head list; /* audit_context->names_list */
struct filename *name;
- int name_len; /* number of chars to log */
- bool hidden; /* don't log this record */
-
u64 ino;
+ struct lsm_prop oprop;
dev_t dev;
- umode_t mode;
kuid_t uid;
kgid_t gid;
dev_t rdev;
- struct lsm_prop oprop;
- struct audit_file_caps fcap;
- unsigned int fcap_ver;
+ int name_len; /* number of chars to log */
+ s16 fcap_ver; /* 8-bit revision, or -1 for NOEVAL */
+ umode_t mode;
+ bool hidden; /* don't log this record */
unsigned char type; /* record type */
/*
* This was an allocated audit_names and not from the array of
@@ -95,6 +93,7 @@ struct audit_names {
* should be freed on syscall exit.
*/
bool should_free;
+ struct audit_file_caps fcap;
};
struct audit_proctitle {
@@ -124,6 +123,7 @@ struct audit_context {
long return_code;/* syscall return code */
u64 prio;
int return_valid; /* return code is valid */
+ int name_count; /* total records in names_list */
/*
* The names_list is the list of all audit_names collected during this
* syscall. The first AUDIT_NAMES entries in the names_list will
@@ -133,7 +133,6 @@ struct audit_context {
* by running the names_list.
*/
struct audit_names preallocated_names[AUDIT_NAMES];
- int name_count; /* total records in names_list */
struct list_head names_list; /* struct audit_names->list anchor */
char *filterkey; /* key for rule that triggered record */
struct path pwd;
@@ -142,10 +141,10 @@ struct audit_context {
struct sockaddr_storage *sockaddr;
size_t sockaddr_len;
/* Save things to print about task_struct */
+ unsigned long personality;
pid_t ppid;
kuid_t uid, euid, suid, fsuid;
kgid_t gid, egid, sgid, fsgid;
- unsigned long personality;
int arch;
pid_t target_pid;
--
2.55.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [RFC PATCH 3/4] audit: return the collected inode entry from a private helper
2026-09-17 14:39 [RFC PATCH 1/4] audit: separate file and process capability storage Christian Göttsche
2026-09-17 14:39 ` [RFC PATCH 2/4] audit: compact name entries and context fields Christian Göttsche
@ 2026-09-17 14:39 ` Christian Göttsche
2026-09-17 14:45 ` sashiko-bot
2026-09-28 22:10 ` [PATCH RFC " Paul Moore
2026-09-17 14:39 ` [RFC PATCH 4/4] audit: retain file paths for descriptor PATH records Christian Göttsche
` (2 subsequent siblings)
4 siblings, 2 replies; 12+ messages in thread
From: Christian Göttsche @ 2026-09-17 14:39 UTC (permalink / raw)
To: audit; +Cc: Paul Moore, Eric Paris, Christian Göttsche
From: Christian Göttsche <cgzones@googlemail.com>
Keep the __audit_inode() interface and collection behavior unchanged.
Return the selected entry, or NULL when collection is skipped or fails,
so audit_file() can attach descriptor-specific information reliably.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
kernel/auditsc.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 464736499c83..b14765cdd56f 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -2237,13 +2237,16 @@ static void audit_copy_inode(struct audit_names *name,
}
/**
- * __audit_inode - store the inode and device from a lookup
+ * audit_inode_entry - store the inode and device from a lookup
* @name: name being audited
* @dentry: dentry being audited
* @flags: attributes for this particular entry
+ *
+ * Return: the collected entry, or NULL if collection was skipped or failed.
*/
-void __audit_inode(struct filename *name, const struct dentry *dentry,
- unsigned int flags)
+static struct audit_names *audit_inode_entry(struct filename *name,
+ const struct dentry *dentry,
+ unsigned int flags)
{
struct audit_context *context = audit_context();
struct inode *inode = d_backing_inode(dentry);
@@ -2254,7 +2257,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
int i;
if (context->context == AUDIT_CTX_UNUSED)
- return;
+ return NULL;
rcu_read_lock();
list_for_each_entry_rcu(e, list, list) {
@@ -2266,7 +2269,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
f->op, f->val)
&& e->rule.action == AUDIT_NEVER) {
rcu_read_unlock();
- return;
+ return NULL;
}
}
}
@@ -2320,7 +2323,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
/* unable to find an entry with both a matching name and type */
n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
if (!n)
- return;
+ return NULL;
if (name) {
n->name = name;
name->refcnt++;
@@ -2338,6 +2341,19 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
}
handle_path(dentry);
audit_copy_inode(n, dentry, inode, flags & AUDIT_INODE_NOEVAL);
+ return n;
+}
+
+/**
+ * __audit_inode - store the inode and device from a lookup
+ * @name: name being audited
+ * @dentry: dentry being audited
+ * @flags: attributes for this particular entry
+ */
+void __audit_inode(struct filename *name, const struct dentry *dentry,
+ unsigned int flags)
+{
+ audit_inode_entry(name, dentry, flags);
}
void __audit_file(const struct file *file)
--
2.55.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [RFC PATCH 4/4] audit: retain file paths for descriptor PATH records
2026-09-17 14:39 [RFC PATCH 1/4] audit: separate file and process capability storage Christian Göttsche
2026-09-17 14:39 ` [RFC PATCH 2/4] audit: compact name entries and context fields Christian Göttsche
2026-09-17 14:39 ` [RFC PATCH 3/4] audit: return the collected inode entry from a private helper Christian Göttsche
@ 2026-09-17 14:39 ` Christian Göttsche
2026-09-17 14:58 ` sashiko-bot
2026-09-28 22:10 ` [PATCH RFC " Paul Moore
2026-09-17 14:50 ` [RFC PATCH 1/4] audit: separate file and process capability storage sashiko-bot
2026-09-28 22:10 ` [PATCH RFC " Paul Moore
4 siblings, 2 replies; 12+ messages in thread
From: Christian Göttsche @ 2026-09-17 14:39 UTC (permalink / raw)
To: audit; +Cc: Paul Moore, Eric Paris, Christian Göttsche
From: Christian Göttsche <cgzones@googlemail.com>
fchown() and the other audit_file() callers collect inode metadata but
emit name=(null), even though file->f_path is available.
Retain the path with balanced dentry and mount references, and use the
existing audit_log_d_path() formatter when no filename was collected.
Release references on context cleanup and entry reuse. Filesystem
exclusions continue to skip entry creation.
The name reflects d_path() at event emission: concurrent renames and
unlinks can affect it. Original lookup names retain precedence.
This adds sizeof(struct path) to each audit_names. With the preceding
capability and layout changes, audit_context grows from 880 to 960 bytes
on the tested x86_64 SELinux configuration and remains in the 1 KiB
kmalloc class. Other LSM configurations can have different object sizes.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
kernel/audit.h | 1 +
kernel/auditsc.c | 19 +++++++++++++++++--
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/kernel/audit.h b/kernel/audit.h
index bd798f8553a0..ef8d25af18c8 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -76,6 +76,7 @@ struct audit_names {
struct list_head list; /* audit_context->names_list */
struct filename *name;
+ struct path fd_path; /* owned audit_file() fallback */
u64 ino;
struct lsm_prop oprop;
dev_t dev;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index b14765cdd56f..3d2f130bc0f8 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -935,6 +935,7 @@ static inline void audit_free_names(struct audit_context *context)
list_del(&n->list);
if (n->name)
putname(n->name);
+ path_put(&n->fd_path);
if (n->should_free)
kfree(n);
}
@@ -1530,7 +1531,9 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
audit_log_n_untrustedstring(ab, n->name->name,
n->name_len);
}
- } else
+ } else if (n->fd_path.dentry)
+ audit_log_d_path(ab, " name=", &n->fd_path);
+ else
audit_log_format(ab, " name=(null)");
if (n->ino != AUDIT_INO_UNSET)
@@ -2222,6 +2225,10 @@ static void audit_copy_inode(struct audit_names *name,
const struct dentry *dentry,
struct inode *inode, unsigned int flags)
{
+ /* An entry can be reused for a different lookup or object. */
+ path_put(&name->fd_path);
+ name->fd_path = (struct path) { };
+
name->ino = inode->i_ino;
name->dev = inode->i_sb->s_dev;
name->mode = inode->i_mode;
@@ -2358,7 +2365,15 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
void __audit_file(const struct file *file)
{
- __audit_inode(NULL, file->f_path.dentry, 0);
+ struct audit_names *n;
+
+ n = audit_inode_entry(NULL, file->f_path.dentry, 0);
+ if (!n)
+ return;
+
+ /* Resolve at event emission, so renames and unlinks can affect the name. */
+ n->fd_path = file->f_path;
+ path_get(&n->fd_path);
}
/**
--
2.55.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [RFC PATCH 3/4] audit: return the collected inode entry from a private helper
2026-09-17 14:39 ` [RFC PATCH 3/4] audit: return the collected inode entry from a private helper Christian Göttsche
@ 2026-09-17 14:45 ` sashiko-bot
2026-09-28 22:10 ` [PATCH RFC " Paul Moore
1 sibling, 0 replies; 12+ messages in thread
From: sashiko-bot @ 2026-09-17 14:45 UTC (permalink / raw)
Cc: audit
> From: Christian Göttsche <cgzones@googlemail.com>
>
> Keep the __audit_inode() interface and collection behavior unchanged.
> Return the selected entry, or NULL when collection is skipped or fails,
> so audit_file() can attach descriptor-specific information reliably.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260917143948.106603-1-cgoettsche@seltendoof.de?part=3
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC PATCH 2/4] audit: compact name entries and context fields
2026-09-17 14:39 ` [RFC PATCH 2/4] audit: compact name entries and context fields Christian Göttsche
@ 2026-09-17 14:49 ` sashiko-bot
2026-09-28 22:10 ` [PATCH RFC " Paul Moore
1 sibling, 0 replies; 12+ messages in thread
From: sashiko-bot @ 2026-09-17 14:49 UTC (permalink / raw)
Cc: audit
> From: Christian Göttsche <cgzones@googlemail.com>
>
> Group aligned name fields and small scalar fields to remove padding. Keep
> file capabilities last so they do not separate inode and pathname metadata.
> Store the per-name file capability revision in s16: it must represent both
> the eight-bit on-disk revision and the -1 AUDIT_INODE_NOEVAL sentinel. Keep
> the existing formatter and its unknown-capability output unchanged.
>
> Move name_count beside return_valid to remove two alignment holes, and
> place personality before the task credential scalars. Preserve the first
> int dummy member required by audit_dummy_context(), all five embedded name
> slots, and the existing allocation and reference lifetimes.
>
> On x86_64 with SELinux this reduces audit_context from 928 to 880 bytes,
> leaving room for descriptor paths while staying below 1 KiB. On the tested
> arm64 configuration without property-bearing LSMs it falls to 872 bytes.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260917143948.106603-1-cgoettsche@seltendoof.de?part=2
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC PATCH 1/4] audit: separate file and process capability storage
2026-09-17 14:39 [RFC PATCH 1/4] audit: separate file and process capability storage Christian Göttsche
` (2 preceding siblings ...)
2026-09-17 14:39 ` [RFC PATCH 4/4] audit: retain file paths for descriptor PATH records Christian Göttsche
@ 2026-09-17 14:50 ` sashiko-bot
2026-09-28 22:10 ` [PATCH RFC " Paul Moore
4 siblings, 0 replies; 12+ messages in thread
From: sashiko-bot @ 2026-09-17 14:50 UTC (permalink / raw)
Cc: audit
> From: Christian Göttsche <cgzones@googlemail.com>
>
> File capabilities need permitted and inheritable sets, an effective flag,
> and a root UID. Process capabilities need four full capability sets but
> neither a file effective flag nor a root UID. Give file capabilities their
> own type instead of storing both representations in audit_cap_data.
>
> This reduces each preallocated audit_names entry by 16 bytes on the tested
> 64-bit configurations, saving 80 bytes per audit context. The BPRM
> capability auxiliary object also shrinks from 144 to 112 bytes. Retain all
> logged fields, including file root IDs and process ambient capabilities;
> record formats and collection behavior are unchanged.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260917143948.106603-1-cgoettsche@seltendoof.de?part=1
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC PATCH 4/4] audit: retain file paths for descriptor PATH records
2026-09-17 14:39 ` [RFC PATCH 4/4] audit: retain file paths for descriptor PATH records Christian Göttsche
@ 2026-09-17 14:58 ` sashiko-bot
2026-09-28 22:10 ` [PATCH RFC " Paul Moore
1 sibling, 0 replies; 12+ messages in thread
From: sashiko-bot @ 2026-09-17 14:58 UTC (permalink / raw)
Cc: audit
> From: Christian Göttsche <cgzones@googlemail.com>
>
> fchown() and the other audit_file() callers collect inode metadata but
> emit name=(null), even though file->f_path is available.
>
> Retain the path with balanced dentry and mount references, and use the
> existing audit_log_d_path() formatter when no filename was collected.
> Release references on context cleanup and entry reuse. Filesystem
> exclusions continue to skip entry creation.
>
> The name reflects d_path() at event emission: concurrent renames and
> unlinks can affect it. Original lookup names retain precedence.
>
> This adds sizeof(struct path) to each audit_names. With the preceding
> capability and layout changes, audit_context grows from 880 to 960 bytes
> on the tested x86_64 SELinux configuration and remains in the 1 KiB
> kmalloc class. Other LSM configurations can have different object sizes.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260917143948.106603-1-cgoettsche@seltendoof.de?part=4
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH RFC 1/4] audit: separate file and process capability storage
2026-09-17 14:39 [RFC PATCH 1/4] audit: separate file and process capability storage Christian Göttsche
` (3 preceding siblings ...)
2026-09-17 14:50 ` [RFC PATCH 1/4] audit: separate file and process capability storage sashiko-bot
@ 2026-09-28 22:10 ` Paul Moore
4 siblings, 0 replies; 12+ messages in thread
From: Paul Moore @ 2026-09-28 22:10 UTC (permalink / raw)
To: Christian Göttsche, audit; +Cc: Eric Paris, Christian Göttsche
On Sep 17, 2026 =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgoettsche@seltendoof.de> wrote:
>
> File capabilities need permitted and inheritable sets, an effective flag,
> and a root UID. Process capabilities need four full capability sets but
> neither a file effective flag nor a root UID. Give file capabilities their
> own type instead of storing both representations in audit_cap_data.
>
> This reduces each preallocated audit_names entry by 16 bytes on the tested
> 64-bit configurations, saving 80 bytes per audit context. The BPRM
> capability auxiliary object also shrinks from 144 to 112 bytes. Retain all
> logged fields, including file root IDs and process ambient capabilities;
> record formats and collection behavior are unchanged.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
> kernel/audit.h | 15 +++++++++------
> kernel/auditsc.c | 2 +-
> 2 files changed, 10 insertions(+), 7 deletions(-)
Nice :)
Merged into audit/dev, thanks!
--
paul-moore.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH RFC 2/4] audit: compact name entries and context fields
2026-09-17 14:39 ` [RFC PATCH 2/4] audit: compact name entries and context fields Christian Göttsche
2026-09-17 14:49 ` sashiko-bot
@ 2026-09-28 22:10 ` Paul Moore
1 sibling, 0 replies; 12+ messages in thread
From: Paul Moore @ 2026-09-28 22:10 UTC (permalink / raw)
To: Christian Göttsche, audit; +Cc: Eric Paris, Christian Göttsche
On Sep 17, 2026 =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgoettsche@seltendoof.de> wrote:
>
> Group aligned name fields and small scalar fields to remove padding. Keep
> file capabilities last so they do not separate inode and pathname metadata.
> Store the per-name file capability revision in s16: it must represent both
> the eight-bit on-disk revision and the -1 AUDIT_INODE_NOEVAL sentinel. Keep
> the existing formatter and its unknown-capability output unchanged.
>
> Move name_count beside return_valid to remove two alignment holes, and
> place personality before the task credential scalars. Preserve the first
> int dummy member required by audit_dummy_context(), all five embedded name
> slots, and the existing allocation and reference lifetimes.
>
> On x86_64 with SELinux this reduces audit_context from 928 to 880 bytes,
> leaving room for descriptor paths while staying below 1 KiB. On the tested
> arm64 configuration without property-bearing LSMs it falls to 872 bytes.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
> kernel/audit.h | 17 ++++++++---------
> 1 file changed, 8 insertions(+), 9 deletions(-)
>
> diff --git a/kernel/audit.h b/kernel/audit.h
> index 7640d2c0fba4..bd798f8553a0 100644
> --- a/kernel/audit.h
> +++ b/kernel/audit.h
> @@ -76,18 +76,16 @@ struct audit_names {
> struct list_head list; /* audit_context->names_list */
>
> struct filename *name;
> - int name_len; /* number of chars to log */
> - bool hidden; /* don't log this record */
> -
> u64 ino;
> + struct lsm_prop oprop;
> dev_t dev;
> - umode_t mode;
> kuid_t uid;
> kgid_t gid;
> dev_t rdev;
> - struct lsm_prop oprop;
> - struct audit_file_caps fcap;
> - unsigned int fcap_ver;
> + int name_len; /* number of chars to log */
> + s16 fcap_ver; /* 8-bit revision, or -1 for NOEVAL */
Should we also change the fcap_ver in audit_aux_data_bprm_fcaps?
> + umode_t mode;
> + bool hidden; /* don't log this record */
> unsigned char type; /* record type */
> /*
> * This was an allocated audit_names and not from the array of
> @@ -95,6 +93,7 @@ struct audit_names {
> * should be freed on syscall exit.
> */
> bool should_free;
> + struct audit_file_caps fcap;
> };
I understand why you moved the fields as you did, but is there any way
we can keep name adjacent to name_len and fcap adjacent to fcap_ver?
Splitting them makes the structure layout awkward to read.
You would need to check that this is safe, but if it helps we could
probably change name_len to a shorter type as PATH_MAX is only 4k and
that limit is part of the UAPI so it isn't easily changed.
> struct audit_proctitle {
> @@ -124,6 +123,7 @@ struct audit_context {
> long return_code;/* syscall return code */
> u64 prio;
> int return_valid; /* return code is valid */
> + int name_count; /* total records in names_list */
I think it would look better to move this below the comment that is
directly below it so it remains adjacent to audit_names. This shouldn't
affect the struct padding/packing.
> /*
> * The names_list is the list of all audit_names collected during this
> * syscall. The first AUDIT_NAMES entries in the names_list will
> @@ -133,7 +133,6 @@ struct audit_context {
> * by running the names_list.
> */
> struct audit_names preallocated_names[AUDIT_NAMES];
> - int name_count; /* total records in names_list */
> struct list_head names_list; /* struct audit_names->list anchor */
> char *filterkey; /* key for rule that triggered record */
> struct path pwd;
> @@ -142,10 +141,10 @@ struct audit_context {
> struct sockaddr_storage *sockaddr;
> size_t sockaddr_len;
> /* Save things to print about task_struct */
> + unsigned long personality;
> pid_t ppid;
> kuid_t uid, euid, suid, fsuid;
> kgid_t gid, egid, sgid, fsgid;
> - unsigned long personality;
> int arch;
>
> pid_t target_pid;
> --
> 2.55.0
--
paul-moore.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH RFC 3/4] audit: return the collected inode entry from a private helper
2026-09-17 14:39 ` [RFC PATCH 3/4] audit: return the collected inode entry from a private helper Christian Göttsche
2026-09-17 14:45 ` sashiko-bot
@ 2026-09-28 22:10 ` Paul Moore
1 sibling, 0 replies; 12+ messages in thread
From: Paul Moore @ 2026-09-28 22:10 UTC (permalink / raw)
To: Christian Göttsche, audit; +Cc: Eric Paris, Christian Göttsche
On Sep 17, 2026 =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgoettsche@seltendoof.de> wrote:
>
> Keep the __audit_inode() interface and collection behavior unchanged.
> Return the selected entry, or NULL when collection is skipped or fails,
> so audit_file() can attach descriptor-specific information reliably.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
> kernel/auditsc.c | 28 ++++++++++++++++++++++------
> 1 file changed, 22 insertions(+), 6 deletions(-)
>
> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> index 464736499c83..b14765cdd56f 100644
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -2237,13 +2237,16 @@ static void audit_copy_inode(struct audit_names *name,
> }
>
> /**
> - * __audit_inode - store the inode and device from a lookup
> + * audit_inode_entry - store the inode and device from a lookup
> * @name: name being audited
> * @dentry: dentry being audited
> * @flags: attributes for this particular entry
> + *
> + * Return: the collected entry, or NULL if collection was skipped or failed.
> */
> -void __audit_inode(struct filename *name, const struct dentry *dentry,
> - unsigned int flags)
> +static struct audit_names *audit_inode_entry(struct filename *name,
> + const struct dentry *dentry,
> + unsigned int flags)
> {
> struct audit_context *context = audit_context();
> struct inode *inode = d_backing_inode(dentry);
> @@ -2254,7 +2257,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
> int i;
>
> if (context->context == AUDIT_CTX_UNUSED)
> - return;
> + return NULL;
>
> rcu_read_lock();
> list_for_each_entry_rcu(e, list, list) {
> @@ -2266,7 +2269,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
> f->op, f->val)
> && e->rule.action == AUDIT_NEVER) {
> rcu_read_unlock();
> - return;
> + return NULL;
> }
> }
> }
> @@ -2320,7 +2323,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
> /* unable to find an entry with both a matching name and type */
> n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
> if (!n)
> - return;
> + return NULL;
> if (name) {
> n->name = name;
> name->refcnt++;
> @@ -2338,6 +2341,19 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
> }
> handle_path(dentry);
> audit_copy_inode(n, dentry, inode, flags & AUDIT_INODE_NOEVAL);
> + return n;
> +}
Why can't we simply make __audit_inode() return an audit_names pointer?
There are only a small number of callers and they look like they could
happily ignore the return value. You would probably need a forward
declaration of audit_names in include/linux/audit.h, but we have a number
of those at the top of the file already, one more isn't going to hurt.
> +/**
> + * __audit_inode - store the inode and device from a lookup
> + * @name: name being audited
> + * @dentry: dentry being audited
> + * @flags: attributes for this particular entry
> + */
> +void __audit_inode(struct filename *name, const struct dentry *dentry,
> + unsigned int flags)
> +{
> + audit_inode_entry(name, dentry, flags);
> }
>
> void __audit_file(const struct file *file)
> --
> 2.55.0
--
paul-moore.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH RFC 4/4] audit: retain file paths for descriptor PATH records
2026-09-17 14:39 ` [RFC PATCH 4/4] audit: retain file paths for descriptor PATH records Christian Göttsche
2026-09-17 14:58 ` sashiko-bot
@ 2026-09-28 22:10 ` Paul Moore
1 sibling, 0 replies; 12+ messages in thread
From: Paul Moore @ 2026-09-28 22:10 UTC (permalink / raw)
To: Christian Göttsche, audit; +Cc: Eric Paris, Christian Göttsche
On Sep 17, 2026 =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgoettsche@seltendoof.de> wrote:
>
> fchown() and the other audit_file() callers collect inode metadata but
> emit name=(null), even though file->f_path is available.
>
> Retain the path with balanced dentry and mount references, and use the
> existing audit_log_d_path() formatter when no filename was collected.
> Release references on context cleanup and entry reuse. Filesystem
> exclusions continue to skip entry creation.
>
> The name reflects d_path() at event emission: concurrent renames and
> unlinks can affect it. Original lookup names retain precedence.
>
> This adds sizeof(struct path) to each audit_names. With the preceding
> capability and layout changes, audit_context grows from 880 to 960 bytes
> on the tested x86_64 SELinux configuration and remains in the 1 KiB
> kmalloc class. Other LSM configurations can have different object sizes.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
> kernel/audit.h | 1 +
> kernel/auditsc.c | 19 +++++++++++++++++--
> 2 files changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/audit.h b/kernel/audit.h
> index bd798f8553a0..ef8d25af18c8 100644
> --- a/kernel/audit.h
> +++ b/kernel/audit.h
> @@ -76,6 +76,7 @@ struct audit_names {
> struct list_head list; /* audit_context->names_list */
>
> struct filename *name;
> + struct path fd_path; /* owned audit_file() fallback */
Since you were looking at ways to reduce the size of audit_names, I
suspect you could probably put name/name_len and fd_path in a union
as you should never have both in use at the same time, right? You would
need some way to indicate which was in use, but if you can steal some
bits back from the name_len field you could use that.
Just a thought, obviously what you have here is just fine.
> u64 ino;
> struct lsm_prop oprop;
> dev_t dev;
> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> index b14765cdd56f..3d2f130bc0f8 100644
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -935,6 +935,7 @@ static inline void audit_free_names(struct audit_context *context)
> list_del(&n->list);
> if (n->name)
> putname(n->name);
> + path_put(&n->fd_path);
Do we need to reset n->fd_path.{dentry,mnt} to NULL just as we do the
audit_context's pwd field? You are already doing something similar in
audit_copy_inode().
> if (n->should_free)
> kfree(n);
> }
> @@ -1530,7 +1531,9 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
> audit_log_n_untrustedstring(ab, n->name->name,
> n->name_len);
> }
> - } else
> + } else if (n->fd_path.dentry)
> + audit_log_d_path(ab, " name=", &n->fd_path);
> + else
> audit_log_format(ab, " name=(null)");
>
> if (n->ino != AUDIT_INO_UNSET)
> @@ -2222,6 +2225,10 @@ static void audit_copy_inode(struct audit_names *name,
> const struct dentry *dentry,
> struct inode *inode, unsigned int flags)
> {
> + /* An entry can be reused for a different lookup or object. */
> + path_put(&name->fd_path);
> + name->fd_path = (struct path) { };
> +
> name->ino = inode->i_ino;
> name->dev = inode->i_sb->s_dev;
> name->mode = inode->i_mode;
> @@ -2358,7 +2365,15 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
>
> void __audit_file(const struct file *file)
> {
> - __audit_inode(NULL, file->f_path.dentry, 0);
> + struct audit_names *n;
> +
> + n = audit_inode_entry(NULL, file->f_path.dentry, 0);
> + if (!n)
> + return;
> +
> + /* Resolve at event emission, so renames and unlinks can affect the name. */
> + n->fd_path = file->f_path;
> + path_get(&n->fd_path);
> }
>
> /**
> --
> 2.55.0
--
paul-moore.com
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-09-28 22:10 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-17 14:39 [RFC PATCH 1/4] audit: separate file and process capability storage Christian Göttsche
2026-09-17 14:39 ` [RFC PATCH 2/4] audit: compact name entries and context fields Christian Göttsche
2026-09-17 14:49 ` sashiko-bot
2026-09-28 22:10 ` [PATCH RFC " Paul Moore
2026-09-17 14:39 ` [RFC PATCH 3/4] audit: return the collected inode entry from a private helper Christian Göttsche
2026-09-17 14:45 ` sashiko-bot
2026-09-28 22:10 ` [PATCH RFC " Paul Moore
2026-09-17 14:39 ` [RFC PATCH 4/4] audit: retain file paths for descriptor PATH records Christian Göttsche
2026-09-17 14:58 ` sashiko-bot
2026-09-28 22:10 ` [PATCH RFC " Paul Moore
2026-09-17 14:50 ` [RFC PATCH 1/4] audit: separate file and process capability storage sashiko-bot
2026-09-28 22:10 ` [PATCH RFC " Paul Moore
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox