From mboxrd@z Thu Jan 1 00:00:00 1970 From: Steve Grubb Subject: [PATCH] audit=0 appears not to completely disable auditing Date: Fri, 9 Mar 2007 15:50:11 -0500 Message-ID: <200703091550.11104.sgrubb@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from discovery.boston.redhat.com (discovery.boston.redhat.com [172.16.80.171]) by mail.boston.redhat.com (8.12.11.20060308/8.12.11) with ESMTP id l29KoF98022759 for ; Fri, 9 Mar 2007 15:50:15 -0500 Content-Disposition: inline List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-audit-bounces@redhat.com Errors-To: linux-audit-bounces@redhat.com To: Linux Audit List-Id: linux-audit@redhat.com Hi, There was a bz, 231371, reporting that current upstream kernels do not completely disable auditing when boot with audit=0 and the audit daemon not configured to run. You can reproduce the problem by: service auditd stop auditctl -e 0 auditctl -w /etc/passwd and you'd get an event in syslog: Mar 9 15:43:04 localhost kernel: audit(1173472984.321:982): auid=4294967295 subj=user_u:system_r:auditctl_t:s0 op=add rule key=(null) list=4 res=1 The patch below solves this problem by checking audit_enabled before creating an audit event. Signed-off-by: Steve Grubb diff -urp linux-2.6.18.x86_64.orig/kernel/audit.c linux-2.6.18.x86_64/kernel/audit.c --- linux-2.6.18.x86_64.orig/kernel/audit.c 2007-03-09 14:08:18.000000000 -0500 +++ linux-2.6.18.x86_64/kernel/audit.c 2007-03-09 14:06:59.000000000 -0500 @@ -238,46 +238,50 @@ void audit_log_lost(const char *message) static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid) { - int old = audit_rate_limit; + if (audit_enabled) { + int old = audit_rate_limit; - if (sid) { - char *ctx = NULL; - u32 len; - int rc; - if ((rc = selinux_ctxid_to_string(sid, &ctx, &len))) - return rc; - else - audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, + if (sid) { + char *ctx = NULL; + u32 len; + int rc; + if ((rc = selinux_ctxid_to_string(sid, &ctx, &len))) + return rc; + else + audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, "audit_rate_limit=%d old=%d by auid=%u subj=%s", - limit, old, loginuid, ctx); - kfree(ctx); - } else - audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, - "audit_rate_limit=%d old=%d by auid=%u", - limit, old, loginuid); + limit, old, loginuid, ctx); + kfree(ctx); + } else + audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, + "audit_rate_limit=%d old=%d by auid=%u", + limit, old, loginuid); + } audit_rate_limit = limit; return 0; } static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid) { - int old = audit_backlog_limit; + if (audit_enabled) { + int old = audit_backlog_limit; - if (sid) { - char *ctx = NULL; - u32 len; - int rc; - if ((rc = selinux_ctxid_to_string(sid, &ctx, &len))) - return rc; - else - audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, + if (sid) { + char *ctx = NULL; + u32 len; + int rc; + if ((rc = selinux_ctxid_to_string(sid, &ctx, &len))) + return rc; + else + audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, "audit_backlog_limit=%d old=%d by auid=%u subj=%s", - limit, old, loginuid, ctx); - kfree(ctx); - } else - audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, - "audit_backlog_limit=%d old=%d by auid=%u", - limit, old, loginuid); + limit, old, loginuid, ctx); + kfree(ctx); + } else + audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, + "audit_backlog_limit=%d old=%d by auid=%u", + limit, old, loginuid); + } audit_backlog_limit = limit; return 0; } @@ -289,21 +293,23 @@ static int audit_set_enabled(int state, if (state != 0 && state != 1) return -EINVAL; - if (sid) { - char *ctx = NULL; - u32 len; - int rc; - if ((rc = selinux_ctxid_to_string(sid, &ctx, &len))) - return rc; - else - audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, + if (audit_enabled || state) { + if (sid) { + char *ctx = NULL; + u32 len; + int rc; + if ((rc = selinux_ctxid_to_string(sid, &ctx, &len))) + return rc; + else + audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, "audit_enabled=%d old=%d by auid=%u subj=%s", - state, old, loginuid, ctx); - kfree(ctx); - } else - audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, - "audit_enabled=%d old=%d by auid=%u", - state, old, loginuid); + state, old, loginuid, ctx); + kfree(ctx); + } else + audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, + "audit_enabled=%d old=%d by auid=%u", + state, old, loginuid); + } audit_enabled = state; return 0; } @@ -317,21 +323,23 @@ static int audit_set_failure(int state, && state != AUDIT_FAIL_PANIC) return -EINVAL; - if (sid) { - char *ctx = NULL; - u32 len; - int rc; - if ((rc = selinux_ctxid_to_string(sid, &ctx, &len))) - return rc; - else - audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, + if (audit_enabled) { + if (sid) { + char *ctx = NULL; + u32 len; + int rc; + if ((rc = selinux_ctxid_to_string(sid, &ctx, &len))) + return rc; + else + audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, "audit_failure=%d old=%d by auid=%u subj=%s", - state, old, loginuid, ctx); - kfree(ctx); - } else - audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, - "audit_failure=%d old=%d by auid=%u", - state, old, loginuid); + state, old, loginuid, ctx); + kfree(ctx); + } else + audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, + "audit_failure=%d old=%d by auid=%u", + state, old, loginuid); + } audit_failure = state; return 0; } @@ -536,22 +544,26 @@ static int audit_receive_msg(struct sk_b if (err < 0) return err; } if (status_get->mask & AUDIT_STATUS_PID) { - int old = audit_pid; - if (sid) { - if ((err = selinux_ctxid_to_string( - sid, &ctx, &len))) - return err; - else + if (audit_enabled) { + int old = audit_pid; + if (sid) { + if ((err = selinux_ctxid_to_string( + sid, &ctx, &len))) + return err; + else + audit_log(NULL, GFP_KERNEL, + AUDIT_CONFIG_CHANGE, + "audit_pid=%d old=%d by auid=%u subj=%s", + status_get->pid, old, + loginuid, ctx); + kfree(ctx); + } else audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, - "audit_pid=%d old=%d by auid=%u subj=%s", - status_get->pid, old, - loginuid, ctx); - kfree(ctx); - } else - audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, "audit_pid=%d old=%d by auid=%u", - status_get->pid, old, loginuid); + status_get->pid, old, + loginuid); + } audit_pid = status_get->pid; } if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) diff -urp linux-2.6.18.x86_64.orig/kernel/auditfilter.c linux-2.6.18.x86_64/kernel/auditfilter.c --- linux-2.6.18.x86_64.orig/kernel/auditfilter.c 2007-03-09 14:08:18.000000000 -0500 +++ linux-2.6.18.x86_64/kernel/auditfilter.c 2007-03-09 14:05:54.000000000 -0500 @@ -95,6 +95,8 @@ extern struct inotify_handle *audit_ih; /* Inotify events we care about. */ #define AUDIT_IN_WATCH IN_MOVE|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF +extern int audit_enabled; + void audit_free_parent(struct inotify_watch *i_watch) { struct audit_parent *parent; @@ -897,7 +899,6 @@ static void audit_update_watch(struct au struct audit_watch *owatch, *nwatch, *nextw; struct audit_krule *r, *nextr; struct audit_entry *oentry, *nentry; - struct audit_buffer *ab; mutex_lock(&audit_filter_mutex); list_for_each_entry_safe(owatch, nextw, &parent->watches, wlist) { @@ -937,13 +938,18 @@ static void audit_update_watch(struct au call_rcu(&oentry->rcu, audit_free_rule_rcu); } - ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); - audit_log_format(ab, "op=updated rules specifying path="); - audit_log_untrustedstring(ab, owatch->path); - audit_log_format(ab, " with dev=%u ino=%lu\n", dev, ino); - audit_log_format(ab, " list=%d res=1", r->listnr); - audit_log_end(ab); - + if (audit_enabled) { + struct audit_buffer *ab; + ab = audit_log_start(NULL, GFP_KERNEL, + AUDIT_CONFIG_CHANGE); + audit_log_format(ab, + "op=updated rules specifying path="); + audit_log_untrustedstring(ab, owatch->path); + audit_log_format(ab, " with dev=%u ino=%lu\n", + dev, ino); + audit_log_format(ab, " list=%d res=1", r->listnr); + audit_log_end(ab); + } audit_remove_watch(owatch); goto add_watch_to_parent; /* event applies to a single watch */ } @@ -962,25 +968,28 @@ static void audit_remove_parent_watches( struct audit_watch *w, *nextw; struct audit_krule *r, *nextr; struct audit_entry *e; - struct audit_buffer *ab; mutex_lock(&audit_filter_mutex); parent->flags |= AUDIT_PARENT_INVALID; list_for_each_entry_safe(w, nextw, &parent->watches, wlist) { list_for_each_entry_safe(r, nextr, &w->rules, rlist) { e = container_of(r, struct audit_entry, rule); - - ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); - audit_log_format(ab, "op=remove rule path="); - audit_log_untrustedstring(ab, w->path); - if (r->filterkey) { - audit_log_format(ab, " key="); - audit_log_untrustedstring(ab, r->filterkey); - } else - audit_log_format(ab, " key=(null)"); - audit_log_format(ab, " list=%d res=1", r->listnr); - audit_log_end(ab); - + if (audit_enabled) { + struct audit_buffer *ab; + ab = audit_log_start(NULL, GFP_KERNEL, + AUDIT_CONFIG_CHANGE); + audit_log_format(ab, "op=remove rule path="); + audit_log_untrustedstring(ab, w->path); + if (r->filterkey) { + audit_log_format(ab, " key="); + audit_log_untrustedstring(ab, + r->filterkey); + } else + audit_log_format(ab, " key=(null)"); + audit_log_format(ab, " list=%d res=1", + r->listnr); + audit_log_end(ab); + } list_del(&r->rlist); list_del_rcu(&e->list); call_rcu(&e->rcu, audit_free_rule_rcu); @@ -1409,6 +1418,9 @@ static void audit_log_rule_change(uid_t { struct audit_buffer *ab; + if (!audit_enabled) + return; + ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); if (!ab) return;