diff options
Diffstat (limited to 'kernel/audit.c')
-rw-r--r-- | kernel/audit.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index 2617d0552400..b683f2b5e866 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -79,6 +79,8 @@ static int audit_rate_limit; | |||
79 | 79 | ||
80 | /* Number of outstanding audit_buffers allowed. */ | 80 | /* Number of outstanding audit_buffers allowed. */ |
81 | static int audit_backlog_limit = 64; | 81 | static int audit_backlog_limit = 64; |
82 | static int audit_backlog_wait_time = 60 * HZ; | ||
83 | static int audit_backlog_wait_overflow = 0; | ||
82 | 84 | ||
83 | /* The identity of the user shutting down the audit system. */ | 85 | /* The identity of the user shutting down the audit system. */ |
84 | uid_t audit_sig_uid = -1; | 86 | uid_t audit_sig_uid = -1; |
@@ -655,6 +657,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask, | |||
655 | struct timespec t; | 657 | struct timespec t; |
656 | unsigned int serial; | 658 | unsigned int serial; |
657 | int reserve; | 659 | int reserve; |
660 | unsigned long timeout_start = jiffies; | ||
658 | 661 | ||
659 | if (!audit_initialized) | 662 | if (!audit_initialized) |
660 | return NULL; | 663 | return NULL; |
@@ -667,8 +670,9 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask, | |||
667 | 670 | ||
668 | while (audit_backlog_limit | 671 | while (audit_backlog_limit |
669 | && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) { | 672 | && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) { |
670 | if (gfp_mask & __GFP_WAIT) { | 673 | if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time |
671 | int ret = 1; | 674 | && time_before(jiffies, timeout_start + audit_backlog_wait_time)) { |
675 | |||
672 | /* Wait for auditd to drain the queue a little */ | 676 | /* Wait for auditd to drain the queue a little */ |
673 | DECLARE_WAITQUEUE(wait, current); | 677 | DECLARE_WAITQUEUE(wait, current); |
674 | set_current_state(TASK_INTERRUPTIBLE); | 678 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -676,12 +680,11 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask, | |||
676 | 680 | ||
677 | if (audit_backlog_limit && | 681 | if (audit_backlog_limit && |
678 | skb_queue_len(&audit_skb_queue) > audit_backlog_limit) | 682 | skb_queue_len(&audit_skb_queue) > audit_backlog_limit) |
679 | ret = schedule_timeout(HZ * 60); | 683 | schedule_timeout(timeout_start + audit_backlog_wait_time - jiffies); |
680 | 684 | ||
681 | __set_current_state(TASK_RUNNING); | 685 | __set_current_state(TASK_RUNNING); |
682 | remove_wait_queue(&audit_backlog_wait, &wait); | 686 | remove_wait_queue(&audit_backlog_wait, &wait); |
683 | if (ret) | 687 | continue; |
684 | continue; | ||
685 | } | 688 | } |
686 | if (audit_rate_check()) | 689 | if (audit_rate_check()) |
687 | printk(KERN_WARNING | 690 | printk(KERN_WARNING |
@@ -690,6 +693,8 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask, | |||
690 | skb_queue_len(&audit_skb_queue), | 693 | skb_queue_len(&audit_skb_queue), |
691 | audit_backlog_limit); | 694 | audit_backlog_limit); |
692 | audit_log_lost("backlog limit exceeded"); | 695 | audit_log_lost("backlog limit exceeded"); |
696 | audit_backlog_wait_time = audit_backlog_wait_overflow; | ||
697 | wake_up(&audit_backlog_wait); | ||
693 | return NULL; | 698 | return NULL; |
694 | } | 699 | } |
695 | 700 | ||