diff options
Diffstat (limited to 'kernel/audit.c')
-rw-r--r-- | kernel/audit.c | 19 |
1 files changed, 8 insertions, 11 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index 00455a9cf027..9c4f1af0c794 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -430,7 +430,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
430 | /* Get message from skb (based on rtnetlink_rcv_skb). Each message is | 430 | /* Get message from skb (based on rtnetlink_rcv_skb). Each message is |
431 | * processed by audit_receive_msg. Malformed skbs with wrong length are | 431 | * processed by audit_receive_msg. Malformed skbs with wrong length are |
432 | * discarded silently. */ | 432 | * discarded silently. */ |
433 | static int audit_receive_skb(struct sk_buff *skb) | 433 | static void audit_receive_skb(struct sk_buff *skb) |
434 | { | 434 | { |
435 | int err; | 435 | int err; |
436 | struct nlmsghdr *nlh; | 436 | struct nlmsghdr *nlh; |
@@ -439,7 +439,7 @@ static int audit_receive_skb(struct sk_buff *skb) | |||
439 | while (skb->len >= NLMSG_SPACE(0)) { | 439 | while (skb->len >= NLMSG_SPACE(0)) { |
440 | nlh = (struct nlmsghdr *)skb->data; | 440 | nlh = (struct nlmsghdr *)skb->data; |
441 | if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) | 441 | if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) |
442 | return 0; | 442 | return; |
443 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); | 443 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); |
444 | if (rlen > skb->len) | 444 | if (rlen > skb->len) |
445 | rlen = skb->len; | 445 | rlen = skb->len; |
@@ -449,23 +449,20 @@ static int audit_receive_skb(struct sk_buff *skb) | |||
449 | netlink_ack(skb, nlh, 0); | 449 | netlink_ack(skb, nlh, 0); |
450 | skb_pull(skb, rlen); | 450 | skb_pull(skb, rlen); |
451 | } | 451 | } |
452 | return 0; | ||
453 | } | 452 | } |
454 | 453 | ||
455 | /* Receive messages from netlink socket. */ | 454 | /* Receive messages from netlink socket. */ |
456 | static void audit_receive(struct sock *sk, int length) | 455 | static void audit_receive(struct sock *sk, int length) |
457 | { | 456 | { |
458 | struct sk_buff *skb; | 457 | struct sk_buff *skb; |
458 | unsigned int qlen; | ||
459 | 459 | ||
460 | if (down_trylock(&audit_netlink_sem)) | 460 | down(&audit_netlink_sem); |
461 | return; | ||
462 | 461 | ||
463 | /* FIXME: this must not cause starvation */ | 462 | for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { |
464 | while ((skb = skb_dequeue(&sk->sk_receive_queue))) { | 463 | skb = skb_dequeue(&sk->sk_receive_queue); |
465 | if (audit_receive_skb(skb) && skb->len) | 464 | audit_receive_skb(skb); |
466 | skb_queue_head(&sk->sk_receive_queue, skb); | 465 | kfree_skb(skb); |
467 | else | ||
468 | kfree_skb(skb); | ||
469 | } | 466 | } |
470 | up(&audit_netlink_sem); | 467 | up(&audit_netlink_sem); |
471 | } | 468 | } |