Audit system development
 help / color / mirror / Atom feed
* [PATCH] Audit: Fix skb leak when audit rate limit is exceeded
@ 2025-09-09 13:10 Gerald Yang
  2025-09-10 23:54 ` Paul Moore
  0 siblings, 1 reply; 2+ messages in thread
From: Gerald Yang @ 2025-09-09 13:10 UTC (permalink / raw)
  To: Casey Schaufler, Paul Moore, linux-security-module, audit; +Cc: gerald.yang.tw

When configuring a small audit rate limit in
/etc/audit/rules.d/audit.rules:
-a always,exit -F arch=b64 -S openat -S truncate -S ftruncate
-F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access -r 100

And then repeatedly triggering permission denied as a normal user:
while :; do cat /proc/1/environ; done

We can see the messages in kernel log:
  [ 2531.862184] audit: rate limit exceeded

The unreclaimable slab objects start to leak quickly. With kmemleak
enabled, many call traces appear like:
unreferenced object 0xffff99144b13f600 (size 232):
  comm "cat", pid 1100, jiffies 4294739144
  hex dump (first 32 bytes):
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  backtrace (crc 8540ec4f):
    kmemleak_alloc+0x4a/0x90
    kmem_cache_alloc_node+0x2ea/0x390
    __alloc_skb+0x174/0x1b0
    audit_log_start+0x198/0x3d0
    audit_log_proctitle+0x32/0x160
    audit_log_exit+0x6c6/0x780
    __audit_syscall_exit+0xee/0x140
    syscall_exit_work+0x12b/0x150
    syscall_exit_to_user_mode_prepare+0x39/0x80
    syscall_exit_to_user_mode+0x11/0x260
    do_syscall_64+0x8c/0x180
    entry_SYSCALL_64_after_hwframe+0x78/0x80

This shows that the skb allocated in audit_log_start() and queued
onto skb_list is never freed.

In audit_log_end(), each skb is dequeued from skb_list and passed
to __audit_log_end(). However, when the audit rate limit is exceeded,
__audit_log_end() simply prints "rate limit exceeded" and returns
without processing the skb. Since the skb is already removed from
skb_list, audit_buffer_free() cannot free it later, leading to a
memory leak.

Fix this by freeing the skb when the rate limit is exceeded.

Signed-off-by: Gerald Yang <gerald.yang@canonical.com>
---
 kernel/audit.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/kernel/audit.c b/kernel/audit.c
index bd7474fd8d2c..89530ddf3807 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2615,8 +2615,10 @@ static void __audit_log_end(struct sk_buff *skb)
 
 		/* queue the netlink packet */
 		skb_queue_tail(&audit_queue, skb);
-	} else
+	} else {
 		audit_log_lost("rate limit exceeded");
+		kfree_skb(skb);
+	}
 }
 
 /**
-- 
2.43.0


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

* Re: [PATCH] Audit: Fix skb leak when audit rate limit is exceeded
  2025-09-09 13:10 [PATCH] Audit: Fix skb leak when audit rate limit is exceeded Gerald Yang
@ 2025-09-10 23:54 ` Paul Moore
  0 siblings, 0 replies; 2+ messages in thread
From: Paul Moore @ 2025-09-10 23:54 UTC (permalink / raw)
  To: Gerald Yang, Casey Schaufler, linux-security-module, audit; +Cc: gerald.yang.tw

On Sep  9, 2025 Gerald Yang <gerald.yang@canonical.com> wrote:
> 
> When configuring a small audit rate limit in
> /etc/audit/rules.d/audit.rules:
> -a always,exit -F arch=b64 -S openat -S truncate -S ftruncate
> -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access -r 100
> 
> And then repeatedly triggering permission denied as a normal user:
> while :; do cat /proc/1/environ; done
> 
> We can see the messages in kernel log:
>   [ 2531.862184] audit: rate limit exceeded
> 
> The unreclaimable slab objects start to leak quickly. With kmemleak
> enabled, many call traces appear like:
> unreferenced object 0xffff99144b13f600 (size 232):
>   comm "cat", pid 1100, jiffies 4294739144
>   hex dump (first 32 bytes):
>     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
>     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
>   backtrace (crc 8540ec4f):
>     kmemleak_alloc+0x4a/0x90
>     kmem_cache_alloc_node+0x2ea/0x390
>     __alloc_skb+0x174/0x1b0
>     audit_log_start+0x198/0x3d0
>     audit_log_proctitle+0x32/0x160
>     audit_log_exit+0x6c6/0x780
>     __audit_syscall_exit+0xee/0x140
>     syscall_exit_work+0x12b/0x150
>     syscall_exit_to_user_mode_prepare+0x39/0x80
>     syscall_exit_to_user_mode+0x11/0x260
>     do_syscall_64+0x8c/0x180
>     entry_SYSCALL_64_after_hwframe+0x78/0x80
> 
> This shows that the skb allocated in audit_log_start() and queued
> onto skb_list is never freed.
> 
> In audit_log_end(), each skb is dequeued from skb_list and passed
> to __audit_log_end(). However, when the audit rate limit is exceeded,
> __audit_log_end() simply prints "rate limit exceeded" and returns
> without processing the skb. Since the skb is already removed from
> skb_list, audit_buffer_free() cannot free it later, leading to a
> memory leak.
> 
> Fix this by freeing the skb when the rate limit is exceeded.
> 
> Signed-off-by: Gerald Yang <gerald.yang@canonical.com>
> ---
>  kernel/audit.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)

Thanks Gerald, this looks good to me, merged into audit/dev with a fixes
tag and a slight tweak to the subject line.

For those of you wondering about -stable, existing kernels, including
Linus' current tree are just fine; this patch fixes a regression found
in commit eb59d494eebd ("audit: add record for multiple task security
contexts") which is only present in the audit/dev branch.

--
paul-moore.com

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

end of thread, other threads:[~2025-09-10 23:55 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-09 13:10 [PATCH] Audit: Fix skb leak when audit rate limit is exceeded Gerald Yang
2025-09-10 23:54 ` Paul Moore

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox