[PATCH] audit=0 appears not to completely disable auditing

Steve Grubb sgrubb at redhat.com
Fri Mar 9 20:50:11 UTC 2007


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 <sgrubb at redhat.com>


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;




More information about the Linux-audit mailing list