Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 12 Jul 2008 21:26:17 GMT
From:      Diego Giagio <diego@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 145115 for review
Message-ID:  <200807122126.m6CLQHJO045863@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=145115

Change 145115 by diego@diego_black on 2008/07/12 21:25:55

	Finish audit support for administrative ipfw events on kernel.

Affected files ...

.. //depot/projects/soc2008/diego-audit/src/sys/bsm/audit_kevents.h#4 edit
.. //depot/projects/soc2008/diego-audit/src/sys/netinet/ip_fw2.c#5 edit
.. //depot/projects/soc2008/diego-audit/src/sys/security/audit/audit.h#8 edit
.. //depot/projects/soc2008/diego-audit/src/sys/security/audit/audit_bsm.c#3 edit
.. //depot/projects/soc2008/diego-audit/src/sys/security/audit/audit_pfil.c#5 edit

Differences ...

==== //depot/projects/soc2008/diego-audit/src/sys/bsm/audit_kevents.h#4 (text) ====

@@ -553,7 +553,9 @@
 #define	AUE_PFIL_POLICY_ADDRULE	43155	/* FreeBSD. */
 #define	AUE_PFIL_POLICY_DELRULE	43156	/* FreeBSD. */
 #define	AUE_PFIL_POLICY_FLUSH	43157	/* FreeBSD. */
-#define	AUE_PFIL_POLICY_TABLE	43158	/* FreeBSD. */
+#define	AUE_PFIL_POLICY_ADDTABLE	43158	/* FreeBSD. */
+#define	AUE_PFIL_POLICY_DELTABLE	43159	/* FreeBSD. */
+#define	AUE_PFIL_POLICY_FLUSHTABLE	43160	/* FreeBSD. */
 
 /*
  * Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the

==== //depot/projects/soc2008/diego-audit/src/sys/netinet/ip_fw2.c#5 (text+ko) ====

@@ -3394,12 +3394,18 @@
 	struct ip_fw *rule, *f, *prev;
 	int l = RULESIZE(input_rule);
 
-	if (chain->rules == NULL && input_rule->rulenum != IPFW_DEFAULT_RULE)
+	if (chain->rules == NULL && input_rule->rulenum != IPFW_DEFAULT_RULE) {
+		AUDIT_CALL(audit_ipfw_addrule(input_rule->set,
+		    input_rule->rulenum, EINVAL));
 		return (EINVAL);
+	}
 
 	rule = malloc(l, M_IPFW, M_NOWAIT | M_ZERO);
-	if (rule == NULL)
+	if (rule == NULL) {
+		AUDIT_CALL(audit_ipfw_addrule(input_rule->set,
+		    input_rule->rulenum, ENOSPC));
 		return (ENOSPC);
+	}
 
 	bcopy(input_rule, rule, l);
 
@@ -3459,6 +3465,7 @@
 	static_count++;
 	static_len += l;
 	IPFW_WUNLOCK(chain);
+	AUDIT_CALL(audit_ipfw_addrule(rule->set, rule->rulenum, 0));
 	DEB(printf("ipfw: installed rule %d, static count now %d\n",
 		rule->rulenum, static_count);)
 	return (0);
@@ -3562,14 +3569,20 @@
 	cmd = (arg >> 24) & 0xff;
 	new_set = (arg >> 16) & 0xff;
 
-	if (cmd > 5 || new_set > RESVD_SET)
+	if (cmd > 5 || new_set > RESVD_SET) {
+		AUDIT_CALL(audit_ipfw_delrule(new_set, rulenum, EINVAL));
 		return EINVAL;
+	}
 	if (cmd == 0 || cmd == 2 || cmd == 5) {
-		if (rulenum >= IPFW_DEFAULT_RULE)
+		if (rulenum >= IPFW_DEFAULT_RULE) {
+			AUDIT_CALL(audit_ipfw_delrule(-1, rulenum, EINVAL));
 			return EINVAL;
+		}
 	} else {
-		if (rulenum > RESVD_SET)	/* old_set */
+		if (rulenum > RESVD_SET) {	/* old_set */
+			AUDIT_CALL(audit_ipfw_delrule(rulenum, -1, EINVAL));
 			return EINVAL;
+		}
 	}
 
 	IPFW_WLOCK(chain);
@@ -3592,41 +3605,68 @@
 		 * rules. prev remains the same throughout the cycle.
 		 */
 		flush_rule_ptrs(chain);
-		while (rule->rulenum == rulenum)
+		while (rule->rulenum == rulenum) {
 			rule = remove_rule(chain, rule, prev);
+			AUDIT_CALL(audit_ipfw_delrule(rule->set, rule->rulenum,
+			    0));
+		}
 		break;
 
 	case 1:	/* delete all rules with given set number */
 		flush_rule_ptrs(chain);
 		rule = chain->rules;
-		while (rule->rulenum < IPFW_DEFAULT_RULE)
-			if (rule->set == rulenum)
+		while (rule->rulenum < IPFW_DEFAULT_RULE) {
+			if (rule->set == rulenum) {
 				rule = remove_rule(chain, rule, prev);
-			else {
+				AUDIT_CALL(audit_ipfw_delrule(rule->set,
+				    rule->rulenum, 0));
+			} else {
 				prev = rule;
 				rule = rule->next;
 			}
+		}
 		break;
 
 	case 2:	/* move rules with given number to new set */
 		rule = chain->rules;
-		for (; rule->rulenum < IPFW_DEFAULT_RULE; rule = rule->next)
-			if (rule->rulenum == rulenum)
+		for (; rule->rulenum < IPFW_DEFAULT_RULE; rule = rule->next) {
+			if (rule->rulenum == rulenum) {
+				AUDIT_CALL(audit_ipfw_delrule(rule->set,
+				    rule->rulenum, 0));
 				rule->set = new_set;
+				AUDIT_CALL(audit_ipfw_addrule(rule->set,
+				    rule->rulenum, 0));
+			}
+		}
 		break;
 
 	case 3: /* move rules with given set number to new set */
-		for (; rule->rulenum < IPFW_DEFAULT_RULE; rule = rule->next)
-			if (rule->set == rulenum)
+		for (; rule->rulenum < IPFW_DEFAULT_RULE; rule = rule->next) {
+			if (rule->set == rulenum) {
+				AUDIT_CALL(audit_ipfw_delrule(rule->set,
+				    rule->rulenum, 0));
 				rule->set = new_set;
+				AUDIT_CALL(audit_ipfw_addrule(rule->set,
+				    rule->rulenum, 0));
+			}
+		}
 		break;
 
 	case 4: /* swap two sets */
 		for (; rule->rulenum < IPFW_DEFAULT_RULE; rule = rule->next)
-			if (rule->set == rulenum)
+			if (rule->set == rulenum) {
+				AUDIT_CALL(audit_ipfw_delrule(rule->set,
+				    rule->rulenum, 0));
 				rule->set = new_set;
-			else if (rule->set == new_set)
+				AUDIT_CALL(audit_ipfw_addrule(rule->set,
+				    rule->rulenum, 0));
+			} else if (rule->set == new_set) {
+				AUDIT_CALL(audit_ipfw_delrule(rule->set,
+				    rule->rulenum, 0));
 				rule->set = rulenum;
+				AUDIT_CALL(audit_ipfw_addrule(rule->set,
+				    rule->rulenum, 0));
+			}
 		break;
 	case 5: /* delete rules with given number and with given set number.
 		 * rulenum - given rule number;
@@ -3640,9 +3680,11 @@
 		}
 		flush_rule_ptrs(chain);
 		while (rule->rulenum == rulenum) {
-			if (rule->set == new_set)
+			if (rule->set == new_set) {
 				rule = remove_rule(chain, rule, prev);
-			else {
+				AUDIT_CALL(audit_ipfw_delrule(rule->set,
+				    rule->rulenum, 0));
+			} else {
 				prev = rule;
 				rule = rule->next;
 			}
@@ -4139,6 +4181,7 @@
 {
 #define	RULE_MAXSIZE	(256*sizeof(u_int32_t))
 	int error;
+	int set;
 	size_t size;
 	struct ip_fw *buf, *rule;
 	u_int32_t rulenum[2];
@@ -4225,7 +4268,6 @@
 			if (!error && sopt->sopt_dir == SOPT_GET)
 				error = sooptcopyout(sopt, rule, size);
 		}
-		AUDIT_CALL(audit_ipfw_addrule(rule, error));
 		free(rule, M_TEMP);
 		break;
 
@@ -4249,13 +4291,26 @@
 		size = sopt->sopt_valsize;
 		if (size == sizeof(u_int32_t))	/* delete or reassign */
 			error = del_entry(&layer3_chain, rulenum[0]);
-		else if (size == 2*sizeof(u_int32_t)) /* set enable/disable */
+		else if (size == 2*sizeof(u_int32_t)) { /* set enable/disable */
 			set_disable =
 			    (set_disable | rulenum[0]) & ~rulenum[1] &
 			    ~(1<<RESVD_SET); /* set RESVD_SET always enabled */
-		else
+
+			/* Audit newly disabled sets */
+			for (set = 0; rulenum[0] != 0; set++, rulenum[0]>>=1) {
+				if (rulenum[0] & 1)
+					AUDIT_CALL(audit_ipfw_delrule(set, -1,
+					    0));
+			}
+
+			/* Audit newly enabled sets */
+			for (set = 0; rulenum[1] != 0; set++, rulenum[1]>>=1) {
+				if (rulenum[1] & 1)
+					AUDIT_CALL(audit_ipfw_addrule(set, -1,
+					    0));
+			}
+		} else
 			error = EINVAL;
-		AUDIT_CALL(audit_ipfw_delrule(NULL /* XXXDG */, error));
 		break;
 
 	case IP_FW_ZERO:
@@ -4281,7 +4336,7 @@
 				break;
 			error = add_table_entry(&layer3_chain, ent.tbl,
 			    ent.addr, ent.masklen, ent.value);
-			AUDIT_CALL(audit_ipfw_table(ent.tbl, error));
+			AUDIT_CALL(audit_ipfw_addtable(ent.tbl, error));
 		}
 		break;
 
@@ -4295,7 +4350,7 @@
 				break;
 			error = del_table_entry(&layer3_chain, ent.tbl,
 			    ent.addr, ent.masklen);
-			AUDIT_CALL(audit_ipfw_table(ent.tbl, error));
+			AUDIT_CALL(audit_ipfw_deltable(ent.tbl, error));
 		}
 		break;
 
@@ -4310,7 +4365,7 @@
 			IPFW_WLOCK(&layer3_chain);
 			error = flush_table(&layer3_chain, tbl);
 			IPFW_WUNLOCK(&layer3_chain);
-			AUDIT_CALL(audit_ipfw_table(tbl, error));
+			AUDIT_CALL(audit_ipfw_flushtable(tbl, error));
 		}
 		break;
 

==== //depot/projects/soc2008/diego-audit/src/sys/security/audit/audit.h#8 (text) ====

@@ -129,11 +129,12 @@
 void	 audit_ipfw_enable(int error);
 void	 audit_ipfw_disable(int error);
 
-struct ip_fw;
-void	 audit_ipfw_addrule(struct ip_fw *rule, int error);
-void	 audit_ipfw_delrule(struct ip_fw *rule, int error);
+void	 audit_ipfw_addrule(int set, int rulenum, int error);
+void	 audit_ipfw_delrule(int set, int rulenum, int error);
 void	 audit_ipfw_flush(int error);
-void	 audit_ipfw_table(u_int table, int error);
+void	 audit_ipfw_addtable(u_int table, int error);
+void	 audit_ipfw_deltable(u_int table, int error);
+void	 audit_ipfw_flushtable(u_int table, int error);
 
 void	 audit_pf_enable(int error);
 void	 audit_pf_disable(int error);

==== //depot/projects/soc2008/diego-audit/src/sys/security/audit/audit_bsm.c#3 (text) ====

@@ -1415,6 +1415,12 @@
 
 	case AUE_PFIL_ENABLE:
 	case AUE_PFIL_DISABLE:
+	case AUE_PFIL_POLICY_ADDRULE:
+	case AUE_PFIL_POLICY_DELRULE:
+	case AUE_PFIL_POLICY_FLUSH:
+	case AUE_PFIL_POLICY_ADDTABLE:
+	case AUE_PFIL_POLICY_DELTABLE:
+	case AUE_PFIL_POLICY_FLUSHTABLE:
 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
 			tok = au_to_text(ar->ar_arg_text);
 			kau_write(rec, tok);

==== //depot/projects/soc2008/diego-audit/src/sys/security/audit/audit_pfil.c#5 (text+ko) ====

@@ -35,101 +35,155 @@
 #include <netinet/in.h>
 #include <netinet/ip_fw.h>
 
+#include <sys/sbuf.h>
+
 #include <bsm/audit_kevents.h>
 
 #include <security/audit/audit.h>
 #include <security/audit/audit_private.h>
 
-/*
- * Create a new audit record. Also add a text token with packet filter's name
- * to the record. This function may return NULL.
- */
-static struct kaudit_record *
-audit_pfil_begin(int event, char *name)
+void
+audit_ipfw_enable(int error)
+{
+	struct kaudit_record *ar;
+
+	ar = audit_begin(AUE_PFIL_ENABLE, curthread);
+	if (ar == NULL)
+		return;
+
+	audit_record_arg_text(ar, "ipfw");
+	audit_commit(ar, error, 0);
+}
+
+void
+audit_ipfw_disable(int error)
 {
 	struct kaudit_record *ar;
 
-	ar = audit_begin(event, curthread /* XXXDG */);
+	ar = audit_begin(AUE_PFIL_DISABLE, curthread);
 	if (ar == NULL)
-		return NULL;
+		return;
+
+	audit_record_arg_text(ar, "ipfw");
+	audit_commit(ar, error, 0);
+}
 
-	audit_record_arg_text(ar, name);
-	return (ar);
+static void
+ipfw_rule_to_text(int set, int rulenum, struct sbuf *sb)
+{
+	sbuf_printf(sb, "ipfw: ");
+	if (set != -1)
+		sbuf_printf(sb, "set=%02u", set);
+	if (rulenum != -1) {
+		if (sbuf_len(sb) > 0)
+			sbuf_cat(sb, ", ");
+		sbuf_printf(sb, "rule=%05u", rulenum);
+	}
+	sbuf_finish(sb);
 }
 
 void
-audit_ipfw_enable(int error)
+audit_ipfw_addrule(int set, int rulenum, int error)
 {
 	struct kaudit_record *ar;
+	struct sbuf sb;
 
-	ar = audit_pfil_begin(AUE_PFIL_ENABLE, "ipfw");
+	ar = audit_begin(AUE_PFIL_POLICY_ADDRULE, curthread);
 	if (ar == NULL)
 		return;
 
+	sbuf_new(&sb, NULL, 0, SBUF_AUTOEXTEND);
+	ipfw_rule_to_text(set, rulenum, &sb);
+	audit_record_arg_text(ar, sbuf_data(&sb));
+	sbuf_delete(&sb);
 	audit_commit(ar, error, 0);
 }
 
 void
-audit_ipfw_disable(int error)
+audit_ipfw_delrule(int set, int rulenum, int error)
 {
 	struct kaudit_record *ar;
+	struct sbuf sb;
 
-	ar = audit_pfil_begin(AUE_PFIL_DISABLE, "ipfw");
+	ar = audit_begin(AUE_PFIL_POLICY_DELRULE, curthread);
 	if (ar == NULL)
 		return;
 
+	sbuf_new(&sb, NULL, 0, SBUF_AUTOEXTEND);
+	ipfw_rule_to_text(set, rulenum, &sb);
+	audit_record_arg_text(ar, sbuf_data(&sb));
+	sbuf_delete(&sb);
 	audit_commit(ar, error, 0);
 }
 
 void
-audit_ipfw_addrule(struct ip_fw *rule, int error)
+audit_ipfw_flush(int error)
 {
 	struct kaudit_record *ar;
 
-	ar = audit_pfil_begin(AUE_PFIL_POLICY_ADDRULE, "ipfw");
+	ar = audit_begin(AUE_PFIL_POLICY_FLUSH, curthread);
 	if (ar == NULL)
 		return;
 
-	/* XXXDG: add tokens */
+	audit_record_arg_text(ar, "ipfw: all");
 	audit_commit(ar, error, 0);
 }
 
+static void
+ipfw_table_to_text(u_int table, struct sbuf *sb)
+{
+	sbuf_printf(sb, "ipfw: table=%u", table);
+	sbuf_finish(sb);
+}
+
 void
-audit_ipfw_delrule(struct ip_fw *rule, int error)
+audit_ipfw_addtable(u_int table, int error)
 {
 	struct kaudit_record *ar;
+	struct sbuf sb;
 
-	ar = audit_pfil_begin(AUE_PFIL_POLICY_DELRULE, "ipfw");
+	ar = audit_begin(AUE_PFIL_POLICY_ADDTABLE, curthread);
 	if (ar == NULL)
 		return;
 
-	/* XXXDG: add tokens */
+	sbuf_new(&sb, NULL, 0, SBUF_AUTOEXTEND);
+	ipfw_table_to_text(table, &sb);
+	audit_record_arg_text(ar, sbuf_data(&sb));
+	sbuf_delete(&sb);
 	audit_commit(ar, error, 0);
 }
 
 void
-audit_ipfw_flush(int error)
+audit_ipfw_deltable(u_int table, int error)
 {
 	struct kaudit_record *ar;
+	struct sbuf sb;
 
-	ar = audit_pfil_begin(AUE_PFIL_POLICY_FLUSH, "ipfw");
+	ar = audit_begin(AUE_PFIL_POLICY_DELTABLE, curthread);
 	if (ar == NULL)
 		return;
 
-	/* XXXDG: add tokens */
+	sbuf_new(&sb, NULL, 0, SBUF_AUTOEXTEND);
+	ipfw_table_to_text(table, &sb);
+	audit_record_arg_text(ar, sbuf_data(&sb));
+	sbuf_delete(&sb);
 	audit_commit(ar, error, 0);
 }
 
 void
-audit_ipfw_table(u_int32_t table, int error)
+audit_ipfw_flushtable(u_int table, int error)
 {
 	struct kaudit_record *ar;
+	struct sbuf sb;
 
-	ar = audit_pfil_begin(AUE_PFIL_POLICY_TABLE, "ipfw");
+	ar = audit_begin(AUE_PFIL_POLICY_FLUSHTABLE, curthread);
 	if (ar == NULL)
 		return;
 
-	/* XXXDG: add tokens */
+	sbuf_new(&sb, NULL, 0, SBUF_AUTOEXTEND);
+	ipfw_table_to_text(table, &sb);
+	audit_record_arg_text(ar, sbuf_data(&sb));
+	sbuf_delete(&sb);
 	audit_commit(ar, error, 0);
 }
 
@@ -138,10 +192,11 @@
 {
 	struct kaudit_record *ar;
 
-	ar = audit_pfil_begin(AUE_PFIL_ENABLE, "pf");
+	ar = audit_begin(AUE_PFIL_ENABLE, curthread);
 	if (ar == NULL)
 		return;
 
+	audit_record_arg_text(ar, "pf");
 	audit_commit(ar, error, 0);
 }
 
@@ -150,10 +205,11 @@
 {
 	struct kaudit_record *ar;
 
-	ar = audit_pfil_begin(AUE_PFIL_DISABLE, "pf");
+	ar = audit_begin(AUE_PFIL_ENABLE, curthread);
 	if (ar == NULL)
 		return;
 
+	audit_record_arg_text(ar, "pf");
 	audit_commit(ar, error, 0);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200807122126.m6CLQHJO045863>