Commit be875f82 authored by Chris Wright's avatar Chris Wright Committed by Linus Torvalds

[PATCH] fix audit skb leak on congested netlink socket

When auditd is congested the kernel's audit system leaks skb's.  First, it
takes them off the audit_buffer sklist at which point they are lost,
second, it allocates a new skb with 0 length payload.  Then (likely still
congested), it repeats this losing the new skb.  Plug the leak by making
sure to requeue the skb, and avoid audit_log_move() on 0 len audit_buffer.
Signed-off-by: default avatarChris Wright <chrisw@osdl.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent de93c78d
...@@ -494,6 +494,10 @@ static void audit_log_move(struct audit_buffer *ab) ...@@ -494,6 +494,10 @@ static void audit_log_move(struct audit_buffer *ab)
char *start; char *start;
int extra = ab->nlh ? 0 : NLMSG_SPACE(0); int extra = ab->nlh ? 0 : NLMSG_SPACE(0);
/* possible resubmission */
if (ab->len == 0)
return;
skb = skb_peek(&ab->sklist); skb = skb_peek(&ab->sklist);
if (!skb || skb_tailroom(skb) <= ab->len + extra) { if (!skb || skb_tailroom(skb) <= ab->len + extra) {
skb = alloc_skb(2 * ab->len + extra, GFP_ATOMIC); skb = alloc_skb(2 * ab->len + extra, GFP_ATOMIC);
...@@ -535,6 +539,7 @@ static inline int audit_log_drain(struct audit_buffer *ab) ...@@ -535,6 +539,7 @@ static inline int audit_log_drain(struct audit_buffer *ab)
} }
if (retval == -EAGAIN && ab->count < 5) { if (retval == -EAGAIN && ab->count < 5) {
++ab->count; ++ab->count;
skb_queue_tail(&ab->sklist, skb);
audit_log_end_irq(ab); audit_log_end_irq(ab);
return 1; return 1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment