diff options
| -rw-r--r-- | kernel/audit.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index f20eee0db7e6..41017685f9f2 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -445,15 +445,20 @@ static void kauditd_retry_skb(struct sk_buff *skb) | |||
| 445 | * | 445 | * |
| 446 | * Description: | 446 | * Description: |
| 447 | * Break the auditd/kauditd connection and move all the records in the retry | 447 | * Break the auditd/kauditd connection and move all the records in the retry |
| 448 | * queue into the hold queue in case auditd reconnects. | 448 | * queue into the hold queue in case auditd reconnects. The audit_cmd_mutex |
| 449 | * must be held when calling this function. | ||
| 449 | */ | 450 | */ |
| 450 | static void auditd_reset(void) | 451 | static void auditd_reset(void) |
| 451 | { | 452 | { |
| 452 | struct sk_buff *skb; | 453 | struct sk_buff *skb; |
| 453 | 454 | ||
| 454 | /* break the connection */ | 455 | /* break the connection */ |
| 456 | if (audit_sock) { | ||
| 457 | sock_put(audit_sock); | ||
| 458 | audit_sock = NULL; | ||
| 459 | } | ||
| 455 | audit_pid = 0; | 460 | audit_pid = 0; |
| 456 | audit_sock = NULL; | 461 | audit_nlk_portid = 0; |
| 457 | 462 | ||
| 458 | /* flush all of the retry queue to the hold queue */ | 463 | /* flush all of the retry queue to the hold queue */ |
| 459 | while ((skb = skb_dequeue(&audit_retry_queue))) | 464 | while ((skb = skb_dequeue(&audit_retry_queue))) |
| @@ -579,7 +584,9 @@ static int kauditd_thread(void *dummy) | |||
| 579 | 584 | ||
| 580 | auditd = 0; | 585 | auditd = 0; |
| 581 | if (AUDITD_BAD(rc, reschedule)) { | 586 | if (AUDITD_BAD(rc, reschedule)) { |
| 587 | mutex_lock(&audit_cmd_mutex); | ||
| 582 | auditd_reset(); | 588 | auditd_reset(); |
| 589 | mutex_unlock(&audit_cmd_mutex); | ||
| 583 | reschedule = 0; | 590 | reschedule = 0; |
| 584 | } | 591 | } |
| 585 | } else | 592 | } else |
| @@ -594,7 +601,9 @@ static int kauditd_thread(void *dummy) | |||
| 594 | auditd = 0; | 601 | auditd = 0; |
| 595 | if (AUDITD_BAD(rc, reschedule)) { | 602 | if (AUDITD_BAD(rc, reschedule)) { |
| 596 | kauditd_hold_skb(skb); | 603 | kauditd_hold_skb(skb); |
| 604 | mutex_lock(&audit_cmd_mutex); | ||
| 597 | auditd_reset(); | 605 | auditd_reset(); |
| 606 | mutex_unlock(&audit_cmd_mutex); | ||
| 598 | reschedule = 0; | 607 | reschedule = 0; |
| 599 | } else | 608 | } else |
| 600 | /* temporary problem (we hope), queue | 609 | /* temporary problem (we hope), queue |
| @@ -623,7 +632,9 @@ quick_loop: | |||
| 623 | if (rc) { | 632 | if (rc) { |
| 624 | auditd = 0; | 633 | auditd = 0; |
| 625 | if (AUDITD_BAD(rc, reschedule)) { | 634 | if (AUDITD_BAD(rc, reschedule)) { |
| 635 | mutex_lock(&audit_cmd_mutex); | ||
| 626 | auditd_reset(); | 636 | auditd_reset(); |
| 637 | mutex_unlock(&audit_cmd_mutex); | ||
| 627 | reschedule = 0; | 638 | reschedule = 0; |
| 628 | } | 639 | } |
| 629 | 640 | ||
| @@ -1010,11 +1021,16 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 1010 | } | 1021 | } |
| 1011 | if (audit_enabled != AUDIT_OFF) | 1022 | if (audit_enabled != AUDIT_OFF) |
| 1012 | audit_log_config_change("audit_pid", new_pid, audit_pid, 1); | 1023 | audit_log_config_change("audit_pid", new_pid, audit_pid, 1); |
| 1013 | audit_pid = new_pid; | 1024 | if (new_pid) { |
| 1014 | audit_nlk_portid = NETLINK_CB(skb).portid; | 1025 | if (audit_sock) |
| 1015 | audit_sock = skb->sk; | 1026 | sock_put(audit_sock); |
| 1016 | if (!new_pid) | 1027 | audit_pid = new_pid; |
| 1028 | audit_nlk_portid = NETLINK_CB(skb).portid; | ||
| 1029 | sock_hold(skb->sk); | ||
| 1030 | audit_sock = skb->sk; | ||
| 1031 | } else { | ||
| 1017 | auditd_reset(); | 1032 | auditd_reset(); |
| 1033 | } | ||
| 1018 | wake_up_interruptible(&kauditd_wait); | 1034 | wake_up_interruptible(&kauditd_wait); |
| 1019 | } | 1035 | } |
| 1020 | if (s.mask & AUDIT_STATUS_RATE_LIMIT) { | 1036 | if (s.mask & AUDIT_STATUS_RATE_LIMIT) { |
| @@ -1283,8 +1299,10 @@ static void __net_exit audit_net_exit(struct net *net) | |||
| 1283 | { | 1299 | { |
| 1284 | struct audit_net *aunet = net_generic(net, audit_net_id); | 1300 | struct audit_net *aunet = net_generic(net, audit_net_id); |
| 1285 | struct sock *sock = aunet->nlsk; | 1301 | struct sock *sock = aunet->nlsk; |
| 1302 | mutex_lock(&audit_cmd_mutex); | ||
| 1286 | if (sock == audit_sock) | 1303 | if (sock == audit_sock) |
| 1287 | auditd_reset(); | 1304 | auditd_reset(); |
| 1305 | mutex_unlock(&audit_cmd_mutex); | ||
| 1288 | 1306 | ||
| 1289 | RCU_INIT_POINTER(aunet->nlsk, NULL); | 1307 | RCU_INIT_POINTER(aunet->nlsk, NULL); |
| 1290 | synchronize_net(); | 1308 | synchronize_net(); |
