PERFORCE change 145115 for review
Diego Giagio
diego at FreeBSD.org
Sat Jul 12 21:26:18 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=145115
Change 145115 by diego at 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);
}
More information about the p4-projects
mailing list