From: Bradley Morgan <include@grrlz.net>
To: Paul Moore <paul@paul-moore.com>
Cc: Eric Paris <eparis@redhat.com>,
Ricardo Robaina <rrobaina@redhat.com>,
audit@vger.kernel.org, linux-kernel@vger.kernel.org,
include@grrlz.net
Subject: [PATCH] audit: move the nlmsg_len fixup from __audit_log_end() to send time
Date: Fri, 14 Aug 2026 01:01:53 +0000 [thread overview]
Message-ID: <20260814010153.14488-1-include@grrlz.net> (raw)
Right now the auditd breakage (nlmsg_len gets set to the payload
length instead of the full message length) is applied when the record
is queued, in __audit_log_end(). That is why
kauditd_send_multicast_skb() has to deep copy every record and then
undo the length on the copy, just so the multicast group still sees a
standard netlink message.
So flip it: finalize the header with the standard full length at
queue time, and apply the auditd length at send time in
kauditd_send_queue(), right before the unicast. Records stay standard
netlink messages the whole time they sit in the queues, and the
multicast copy stops needing its own fixup. The copy itself stays,
because the rewrite still lands in the data region the listeners
already hold.
auditd sees the same bytes as before: the fixup is computed from
skb->len and that does not change between queueing and sending, so
records that come back around through the retry and hold queues get
the same value again. Reply and rule list skbs are built with
nlmsg_put() and go out on their own paths, none of that is touched.
This came out of reviewing Ricardo's "use copied skb length" patch,
where I suggested moving the fixup as the more interesting cleanup.
Reviewed-by: Ricardo Robaina <rrobaina@redhat.com>
Tested-by: Ricardo Robaina <rrobaina@redhat.com>
Signed-off-by: Bradley Morgan <include@grrlz.net>
Link: https://lore.kernel.org/r/20260810125726.775689-2-rrobaina@redhat.com
---
kernel/audit.c | 30 +++++++++++++-----------------
1 file changed, 13 insertions(+), 17 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index 9412af9144bc..bcfed6e3678e 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -802,6 +802,12 @@ static int kauditd_send_queue(struct sock *sk, u32 portid,
if (skb_hook)
(*skb_hook)(skb);
+ /*
+ * auditd wants nlmsg_len to be the payload length, not the
+ * full length, so break it here at send time.
+ */
+ nlmsg_hdr(skb)->nlmsg_len = skb->len - NLMSG_HDRLEN;
+
/* can we send to anyone via unicast? */
if (!sk) {
if (err_hook)
@@ -849,7 +855,6 @@ static void kauditd_send_multicast_skb(struct sk_buff *skb)
{
struct sk_buff *copy;
struct sock *sock = audit_get_sk(&init_net);
- struct nlmsghdr *nlh;
/* NOTE: we are not taking an additional reference for init_net since
* we don't have to worry about it going away */
@@ -858,20 +863,12 @@ static void kauditd_send_multicast_skb(struct sk_buff *skb)
return;
/*
- * The seemingly wasteful skb_copy() rather than bumping the refcount
- * using skb_get() is necessary because non-standard mods are made to
- * the skb by the original kaudit unicast socket send routine. The
- * existing auditd daemon assumes this breakage. Fixing this would
- * require co-ordinating a change in the established protocol between
- * the kaudit kernel subsystem and the auditd userspace code. There is
- * no reason for new multicast clients to continue with this
- * non-compliance.
+ * skb_copy() rather than skb_get(): kauditd_send_queue() breaks
+ * nlmsg_len for auditd, keep the listeners on a standard message.
*/
copy = skb_copy(skb, GFP_KERNEL);
if (!copy)
return;
- nlh = nlmsg_hdr(copy);
- nlh->nlmsg_len = skb->len;
nlmsg_multicast(sock, copy, 0, AUDIT_NLGRP_READLOG, GFP_KERNEL);
}
@@ -2785,13 +2782,12 @@ int audit_signal_info(int sig, struct task_struct *t)
*/
static void __audit_log_end(struct sk_buff *skb)
{
- struct nlmsghdr *nlh;
-
if (audit_rate_check()) {
- /* setup the netlink header, see the comments in
- * kauditd_send_multicast_skb() for length quirks */
- nlh = nlmsg_hdr(skb);
- nlh->nlmsg_len = skb->len - NLMSG_HDRLEN;
+ /*
+ * Records are built without keeping nlmsg_len up to date,
+ * finalize it here with the full message length.
+ */
+ nlmsg_end(skb, nlmsg_hdr(skb));
/* queue the netlink packet */
skb_queue_tail(&audit_queue, skb);
--
2.47.3
next reply other threads:[~2026-08-14 1:01 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-14 1:01 Bradley Morgan [this message]
2026-08-14 1:58 ` [PATCH] audit: move the nlmsg_len fixup from __audit_log_end() to send time sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260814010153.14488-1-include@grrlz.net \
--to=include@grrlz.net \
--cc=audit@vger.kernel.org \
--cc=eparis@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=paul@paul-moore.com \
--cc=rrobaina@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.