summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guy Briggs <rgb@redhat.com>2014-08-21 13:40:41 -0400
committerEric Paris <eparis@redhat.com>2014-09-23 16:37:54 -0400
commit54e05eddbe507d54f1df18c2680d4f614af9e133 (patch)
tree05a954d24f606dba272ca0a2e9da43e4117feaba
parent219ca39427bf6c46c4e1473493e33bc00635e99b (diff)
audit: set nlmsg_len for multicast messages.
Report: Looking at your example code in http://people.redhat.com/rbriggs/audit-multicast-listen/audit-multicast-listen.c, it seems that nlmsg_len field in the received messages is supposed to contain the length of the header + payload, but it is always set to the size of the header only, i.e. 16. The example program works, because the printf format specifies the minimum width, not "precision", so it simply prints out the payload until the first zero byte. This isn't too much of a problem, but precludes the use of recvmmsg, iiuc? (gdb) p *(struct nlmsghdr*)nlh $14 = {nlmsg_len = 16, nlmsg_type = 1100, nlmsg_flags = 0, nlmsg_seq = 0, nlmsg_pid = 9910} The only time nlmsg_len would have been updated was at audit_buffer_alloc() inside audit_log_start() and never updated after. It should arguably be done in audit_log_vformat(), but would be more efficient in audit_log_end(). Reported-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
-rw-r--r--kernel/audit.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index 7aef7cbd7bcf..d20f00ff7bb5 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1949,6 +1949,7 @@ void audit_log_end(struct audit_buffer *ab)
} else {
struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
+ nlh->nlmsg_len = ab->skb->len;
kauditd_send_multicast_skb(ab->skb);
/*
@@ -1960,7 +1961,7 @@ void audit_log_end(struct audit_buffer *ab)
* protocol between the kaudit kernel subsystem and the auditd
* userspace code.
*/
- nlh->nlmsg_len = ab->skb->len - NLMSG_HDRLEN;
+ nlh->nlmsg_len -= NLMSG_HDRLEN;
if (audit_pid) {
skb_queue_tail(&audit_skb_queue, ab->skb);