aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/audit.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/audit.c')
-rw-r--r--kernel/audit.c61
1 files changed, 38 insertions, 23 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index 6f344b44d3d3..e5bdba3e3ae1 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -620,6 +620,42 @@ static int __init audit_enable(char *str)
620 620
621__setup("audit=", audit_enable); 621__setup("audit=", audit_enable);
622 622
623static void audit_buffer_free(struct audit_buffer *ab)
624{
625 unsigned long flags;
626
627 atomic_dec(&audit_backlog);
628 spin_lock_irqsave(&audit_freelist_lock, flags);
629 if (++audit_freelist_count > AUDIT_MAXFREE)
630 kfree(ab);
631 else
632 list_add(&ab->list, &audit_freelist);
633 spin_unlock_irqrestore(&audit_freelist_lock, flags);
634}
635
636static struct audit_buffer * audit_buffer_alloc(int gfp_mask)
637{
638 unsigned long flags;
639 struct audit_buffer *ab = NULL;
640
641 spin_lock_irqsave(&audit_freelist_lock, flags);
642 if (!list_empty(&audit_freelist)) {
643 ab = list_entry(audit_freelist.next,
644 struct audit_buffer, list);
645 list_del(&ab->list);
646 --audit_freelist_count;
647 }
648 spin_unlock_irqrestore(&audit_freelist_lock, flags);
649
650 if (!ab) {
651 ab = kmalloc(sizeof(*ab), GFP_ATOMIC);
652 if (!ab)
653 goto out;
654 }
655 atomic_inc(&audit_backlog);
656out:
657 return ab;
658}
623 659
624/* Obtain an audit buffer. This routine does locking to obtain the 660/* Obtain an audit buffer. This routine does locking to obtain the
625 * audit buffer, but then no locking is required for calls to 661 * audit buffer, but then no locking is required for calls to
@@ -630,7 +666,6 @@ __setup("audit=", audit_enable);
630struct audit_buffer *audit_log_start(struct audit_context *ctx) 666struct audit_buffer *audit_log_start(struct audit_context *ctx)
631{ 667{
632 struct audit_buffer *ab = NULL; 668 struct audit_buffer *ab = NULL;
633 unsigned long flags;
634 struct timespec t; 669 struct timespec t;
635 unsigned int serial; 670 unsigned int serial;
636 671
@@ -649,23 +684,12 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx)
649 return NULL; 684 return NULL;
650 } 685 }
651 686
652 spin_lock_irqsave(&audit_freelist_lock, flags); 687 ab = audit_buffer_alloc(GFP_ATOMIC);
653 if (!list_empty(&audit_freelist)) {
654 ab = list_entry(audit_freelist.next,
655 struct audit_buffer, list);
656 list_del(&ab->list);
657 --audit_freelist_count;
658 }
659 spin_unlock_irqrestore(&audit_freelist_lock, flags);
660
661 if (!ab)
662 ab = kmalloc(sizeof(*ab), GFP_ATOMIC);
663 if (!ab) { 688 if (!ab) {
664 audit_log_lost("out of memory in audit_log_start"); 689 audit_log_lost("out of memory in audit_log_start");
665 return NULL; 690 return NULL;
666 } 691 }
667 692
668 atomic_inc(&audit_backlog);
669 skb_queue_head_init(&ab->sklist); 693 skb_queue_head_init(&ab->sklist);
670 694
671 ab->ctx = ctx; 695 ab->ctx = ctx;
@@ -824,8 +848,6 @@ static void audit_log_end_irq(struct audit_buffer *ab)
824 * be called in an irq context. */ 848 * be called in an irq context. */
825static void audit_log_end_fast(struct audit_buffer *ab) 849static void audit_log_end_fast(struct audit_buffer *ab)
826{ 850{
827 unsigned long flags;
828
829 BUG_ON(in_irq()); 851 BUG_ON(in_irq());
830 if (!ab) 852 if (!ab)
831 return; 853 return;
@@ -836,14 +858,7 @@ static void audit_log_end_fast(struct audit_buffer *ab)
836 if (audit_log_drain(ab)) 858 if (audit_log_drain(ab))
837 return; 859 return;
838 } 860 }
839 861 audit_buffer_free(ab);
840 atomic_dec(&audit_backlog);
841 spin_lock_irqsave(&audit_freelist_lock, flags);
842 if (++audit_freelist_count > AUDIT_MAXFREE)
843 kfree(ab);
844 else
845 list_add(&ab->list, &audit_freelist);
846 spin_unlock_irqrestore(&audit_freelist_lock, flags);
847} 862}
848 863
849/* Send or queue the message in the audit buffer, depending on the 864/* Send or queue the message in the audit buffer, depending on the