From 4f7b54e17eddac93c78151ffc80b8437ab11c90b Mon Sep 17 00:00:00 2001 From: Ricardo Robaina Date: Wed, 8 Oct 2025 11:27:19 -0300 Subject: [PATCH 1/3] audit: fix comment misindentation in audit.h Minor comment misindentation adjustment. Signed-off-by: Ricardo Robaina Signed-off-by: Paul Moore --- kernel/audit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/audit.h b/kernel/audit.h index 0f05933a173b..7c401729e21b 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -138,7 +138,7 @@ struct audit_context { struct audit_aux_data *aux_pids; struct sockaddr_storage *sockaddr; size_t sockaddr_len; - /* Save things to print about task_struct */ + /* Save things to print about task_struct */ pid_t ppid; kuid_t uid, euid, suid, fsuid; kgid_t gid, egid, sgid, fsgid; From 77563f3d4704206c8f6626852365591aa4e0b779 Mon Sep 17 00:00:00 2001 From: Gongwei Li Date: Wed, 5 Nov 2025 18:36:19 +0800 Subject: [PATCH 2/3] audit: Use kzalloc() instead of kmalloc()/memset() in audit_krule_to_data() Replace kmalloc+memset by kzalloc for better readability and simplicity. This addresses the warning below: WARNING: kzalloc should be used for data, instead of kmalloc/memset Signed-off-by: Gongwei Li [PM: subject and description tweaks] Signed-off-by: Paul Moore --- kernel/auditfilter.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index c401082d9b25..6a86c0683b67 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -638,10 +638,9 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule) void *bufp; int i; - data = kmalloc(struct_size(data, buf, krule->buflen), GFP_KERNEL); + data = kzalloc(struct_size(data, buf, krule->buflen), GFP_KERNEL); if (unlikely(!data)) return NULL; - memset(data, 0, sizeof(*data)); data->flags = krule->flags | krule->listnr; data->action = krule->action; From c8a3dfe7315945ebcc80ed5be8267920b609649a Mon Sep 17 00:00:00 2001 From: Ricardo Robaina Date: Fri, 31 Oct 2025 09:33:28 -0300 Subject: [PATCH 3/3] audit: merge loops in __audit_inode_child() Whenever there's audit context, __audit_inode_child() gets called numerous times, which can lead to high latency in scenarios that create too many sysfs/debugfs entries at once, for instance, upon device_add_disk() invocation. # uname -r 6.18.0-rc2+ # auditctl -a always,exit -F path=/tmp -k foo # time insmod loop max_loop=1000 real 0m46.676s user 0m0.000s sys 0m46.405s # perf record -a insmod loop max_loop=1000 # perf report --stdio |grep __audit_inode_child 32.73% insmod [kernel.kallsyms] [k] __audit_inode_child __audit_inode_child() searches for both the parent and the child in two different loops that iterate over the same list. This process can be optimized by merging these into a single loop, without changing the function behavior or affecting the code's readability. This patch merges the two loops that walk through the list context->names_list into a single loop. This optimization resulted in around 51% performance enhancement for the benchmark. # uname -r 6.18.0-rc2-enhancedv3+ # auditctl -a always,exit -F path=/tmp -k foo # time insmod loop max_loop=1000 real 0m22.899s user 0m0.001s sys 0m22.652s Signed-off-by: Ricardo Robaina Signed-off-by: Paul Moore --- kernel/auditsc.c | 47 +++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/kernel/auditsc.c b/kernel/auditsc.c index d1966144bdfe..dd0563a8e0be 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -2416,41 +2416,36 @@ void __audit_inode_child(struct inode *parent, if (inode) handle_one(inode); - /* look for a parent entry first */ - list_for_each_entry(n, &context->names_list, list) { - if (!n->name || - (n->type != AUDIT_TYPE_PARENT && - n->type != AUDIT_TYPE_UNKNOWN)) - continue; - - if (n->ino == parent->i_ino && n->dev == parent->i_sb->s_dev && - !audit_compare_dname_path(dname, - n->name->name, n->name_len)) { - if (n->type == AUDIT_TYPE_UNKNOWN) - n->type = AUDIT_TYPE_PARENT; - found_parent = n; - break; - } - } - - cond_resched(); - - /* is there a matching child entry? */ list_for_each_entry(n, &context->names_list, list) { /* can only match entries that have a name */ - if (!n->name || - (n->type != type && n->type != AUDIT_TYPE_UNKNOWN)) + if (!n->name) continue; - if (!strcmp(dname->name, n->name->name) || - !audit_compare_dname_path(dname, n->name->name, + /* look for a parent entry first */ + if (!found_parent && + (n->type == AUDIT_TYPE_PARENT || n->type == AUDIT_TYPE_UNKNOWN) && + (n->ino == parent->i_ino && n->dev == parent->i_sb->s_dev && + !audit_compare_dname_path(dname, n->name->name, n->name_len))) { + n->type = AUDIT_TYPE_PARENT; + found_parent = n; + if (found_child) + break; + continue; + } + + /* is there a matching child entry? */ + if (!found_child && + (n->type == type || n->type == AUDIT_TYPE_UNKNOWN) && + (!strcmp(dname->name, n->name->name) || + !audit_compare_dname_path(dname, n->name->name, found_parent ? found_parent->name_len : - AUDIT_NAME_FULL)) { + AUDIT_NAME_FULL))) { if (n->type == AUDIT_TYPE_UNKNOWN) n->type = type; found_child = n; - break; + if (found_parent) + break; } }