Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754207Ab3JXHb2 (ORCPT ); Thu, 24 Oct 2013 03:31:28 -0400 Received: from cn.fujitsu.com ([222.73.24.84]:2387 "EHLO song.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1754137Ab3JXHbJ (ORCPT ); Thu, 24 Oct 2013 03:31:09 -0400 X-IronPort-AV: E=Sophos;i="4.93,560,1378828800"; d="scan'208";a="8847758" From: Gao feng To: linux-kernel@vger.kernel.org, linux-audit@redhat.com Cc: containers@lists.linux-foundation.org, ebiederm@xmission.com, serge.hallyn@ubuntu.com, eparis@redhat.com, sgrubb@redhat.com, toshi.okajima@jp.fujitsu.com, Gao feng Subject: [PATCH 19/20] audit: make audit_backlog_limit per audit namespace Date: Thu, 24 Oct 2013 15:32:04 +0800 Message-Id: <1382599925-25143-20-git-send-email-gaofeng@cn.fujitsu.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1382599925-25143-1-git-send-email-gaofeng@cn.fujitsu.com> References: <1382599925-25143-1-git-send-email-gaofeng@cn.fujitsu.com> X-MIMETrack: Itemize by SMTP Server on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2013/10/24 15:28:23, Serialize by Router on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2013/10/24 15:28:32, Serialize complete at 2013/10/24 15:28:32 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5859 Lines: 167 This patch makes audit_backlog_limit per audit namespace, so we can limit the memory usage of audit namespace through limit the value of auditns's audit_backlog_limit. By default, the backlog_limit of new created audit namespace is zero, so processes in this auditns has no ability to generate audit log. Signed-off-by: Gao feng --- include/linux/audit_namespace.h | 2 ++ kernel/audit.c | 47 +++++++++++++++++++++++------------------ 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/include/linux/audit_namespace.h b/include/linux/audit_namespace.h index b17f052..4648b4f 100644 --- a/include/linux/audit_namespace.h +++ b/include/linux/audit_namespace.h @@ -14,6 +14,8 @@ struct audit_namespace { int pid; /* portid of the auditd process's netlink socket */ int portid; + /* number of outstanding audit_buffers allowed */ + int backlog_limit; struct user_namespace *user_ns; struct sk_buff_head queue; /* queue of skbs to send to auditd when/if it comes back */ diff --git a/kernel/audit.c b/kernel/audit.c index 86212d3..63797557 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -94,8 +94,6 @@ static int audit_failure = AUDIT_FAIL_PRINTK; * audit records being dropped. */ static int audit_rate_limit; -/* Number of outstanding audit_buffers allowed. */ -static int audit_backlog_limit = 64; static int audit_backlog_wait_time = 60 * HZ; static int audit_backlog_wait_overflow = 0; @@ -210,15 +208,7 @@ static inline int audit_rate_check(void) return retval; } -/** - * audit_log_lost - conditionally log lost audit message event - * @message: the message stating reason for lost audit message - * - * Emit at least 1 message per second, even if audit_rate_check is - * throttling. - * Always increment the lost messages counter. -*/ -void audit_log_lost(const char *message) +void audit_log_lost_ns(struct audit_namespace *ns, const char *message) { static unsigned long last_msg = 0; static DEFINE_SPINLOCK(lock); @@ -240,18 +230,31 @@ void audit_log_lost(const char *message) spin_unlock_irqrestore(&lock, flags); } - if (print) { + if (print && (ns == &init_audit_ns)) { if (printk_ratelimit()) printk(KERN_WARNING "audit: audit_lost=%d audit_rate_limit=%d " "audit_backlog_limit=%d\n", atomic_read(&audit_lost), audit_rate_limit, - audit_backlog_limit); + ns->backlog_limit); audit_panic(message); } } +/** + * audit_log_lost - conditionally log lost audit message event + * @message: the message stating reason for lost audit message + * + * Emit at least 1 message per second, even if audit_rate_check is + * throttling. + * Always increment the lost messages counter. +*/ +void audit_log_lost(const char *message) +{ + return audit_log_lost_ns(&init_audit_ns, message); +} + static int audit_log_config_change(struct audit_namespace *ns, char *function_name, int new, int old, @@ -308,7 +311,8 @@ static int audit_set_rate_limit(int limit) static int audit_set_backlog_limit(int limit) { - return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, limit); + return audit_do_config_change("audit_backlog_limit", + &init_audit_ns.backlog_limit, limit); } static int audit_set_enabled(int state) @@ -346,7 +350,7 @@ static int audit_set_failure(int state) static void audit_hold_skb(struct audit_namespace *ns, struct sk_buff *skb) { if (audit_default && - skb_queue_len(&ns->hold_queue) < audit_backlog_limit) + skb_queue_len(&ns->hold_queue) < ns->backlog_limit) skb_queue_tail(&ns->hold_queue, skb); else kfree_skb(skb); @@ -675,7 +679,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) status_set.failure = audit_failure; status_set.pid = ns->pid; status_set.rate_limit = audit_rate_limit; - status_set.backlog_limit = audit_backlog_limit; + status_set.backlog_limit = ns->backlog_limit; status_set.lost = atomic_read(&audit_lost); status_set.backlog = skb_queue_len(&ns->queue); @@ -971,6 +975,7 @@ static int __init audit_init(void) init_audit_ns.pid = 0; init_audit_ns.portid = 0; + init_audit_ns.backlog_limit = 64; init_audit_ns.kauditd_task = NULL; skb_queue_head_init(&init_audit_ns.queue); skb_queue_head_init(&init_audit_ns.hold_queue); @@ -1129,8 +1134,8 @@ static void wait_for_auditd(struct audit_namespace *ns, set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&ns->backlog_wait, &wait); - if (audit_backlog_limit && - skb_queue_len(&ns->queue) > audit_backlog_limit) + if (ns->backlog_limit && + skb_queue_len(&ns->queue) > ns->backlog_limit) schedule_timeout(sleep_time); __set_current_state(TASK_RUNNING); @@ -1167,8 +1172,8 @@ audit_log_start_ns(struct audit_namespace *ns, reserve = 5; /* Allow atomic callers to go up to five entries over the normal backlog limit */ - while (audit_backlog_limit - && skb_queue_len(&ns->queue) > audit_backlog_limit + reserve) { + while (ns->backlog_limit + && skb_queue_len(&ns->queue) > ns->backlog_limit + reserve) { if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time) { unsigned long sleep_time; @@ -1184,7 +1189,7 @@ audit_log_start_ns(struct audit_namespace *ns, "audit: audit_backlog=%d > " "audit_backlog_limit=%d\n", skb_queue_len(&ns->queue), - audit_backlog_limit); + ns->backlog_limit); audit_log_lost("backlog limit exceeded"); audit_backlog_wait_time = audit_backlog_wait_overflow; wake_up(&init_audit_ns.backlog_wait); -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/