From owner-p4-projects@FreeBSD.ORG Sat Jul 12 21:26:18 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 04B65106568D; Sat, 12 Jul 2008 21:26:18 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BD1F81065688 for ; Sat, 12 Jul 2008 21:26:17 +0000 (UTC) (envelope-from diego@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id ADE5A8FC14 for ; Sat, 12 Jul 2008 21:26:17 +0000 (UTC) (envelope-from diego@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m6CLQH9X045865 for ; Sat, 12 Jul 2008 21:26:17 GMT (envelope-from diego@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.2/8.14.1/Submit) id m6CLQHJO045863 for perforce@freebsd.org; Sat, 12 Jul 2008 21:26:17 GMT (envelope-from diego@FreeBSD.org) Date: Sat, 12 Jul 2008 21:26:17 GMT Message-Id: <200807122126.m6CLQHJO045863@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to diego@FreeBSD.org using -f From: Diego Giagio To: Perforce Change Reviews Cc: Subject: PERFORCE change 145115 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 12 Jul 2008 21:26:18 -0000 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<>=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 #include +#include + #include #include #include -/* - * 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); }