Date: Sun, 17 Aug 2008 03:23:53 GMT From: Diego Giagio <diego@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 147626 for review Message-ID: <200808170323.m7H3Nrpe032034@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=147626 Change 147626 by diego@diego_black on 2008/08/17 03:23:45 Many many changes, including: - Add audit_pfil_enter and audit_pfil_exit like their syscall equivalents. - Add support for creating records inside locks and by ithreads by preallocating records using M_NOWAIT - Add support for network statefull records (flow records) on ipfw - Add support for nested record generation, specially usefull on ithreads context. - Improve admin records generation. - We don't need audit_pfil.c anymore, remove it. - We don't need AUDIT_CALL macro anymore, remove it. - More to come. Affected files ... .. //depot/projects/soc2008/diego-audit/src/sys/conf/files#8 edit .. //depot/projects/soc2008/diego-audit/src/sys/netinet/ip_fw.h#4 edit .. //depot/projects/soc2008/diego-audit/src/sys/netinet/ip_fw2.c#7 edit .. //depot/projects/soc2008/diego-audit/src/sys/netinet/ip_fw_pfil.c#4 edit .. //depot/projects/soc2008/diego-audit/src/sys/security/audit/audit.c#7 edit .. //depot/projects/soc2008/diego-audit/src/sys/security/audit/audit_private.h#5 edit .. //depot/projects/soc2008/diego-audit/src/sys/security/audit/audit_syscalls.c#2 edit Differences ... ==== //depot/projects/soc2008/diego-audit/src/sys/conf/files#8 (text+ko) ==== @@ -2115,7 +2115,6 @@ security/audit/audit_bsm.c optional audit security/audit/audit_bsm_klib.c optional audit security/audit/audit_bsm_token.c optional audit -security/audit/audit_pfil.c optional audit security/audit/audit_pipe.c optional audit security/audit/audit_syscalls.c standard security/audit/audit_trigger.c optional audit ==== //depot/projects/soc2008/diego-audit/src/sys/netinet/ip_fw.h#4 (text+ko) ==== @@ -102,6 +102,7 @@ O_PROBE_STATE, /* none */ O_KEEP_STATE, /* none */ + //O_AUDIT, /* none */ O_LIMIT, /* ipfw_insn_limit */ O_LIMIT_PARENT, /* dyn_type, not an opcode. */ ==== //depot/projects/soc2008/diego-audit/src/sys/netinet/ip_fw2.c#7 (text+ko) ==== @@ -104,6 +104,8 @@ #include <machine/in_cksum.h> /* XXX for in_cksum */ +#include <bsm/audit_kevents.h> + #include <security/audit/audit.h> #include <security/mac/mac_framework.h> @@ -1036,27 +1038,57 @@ return i; } +static void +addr_port_to_sin(u_int32_t addr, u_int16_t port, struct sockaddr_in *sin) +{ + sin->sin_len = sizeof(struct sockaddr_in); + sin->sin_family = PF_INET; + sin->sin_port = port; + sin->sin_addr.s_addr = addr; +} + /** * unlink a dynamic rule from a chain. prev is a pointer to * the previous one, q is a pointer to the rule to delete, * head is a pointer to the head of the queue. * Modifies q and potentially also head. */ -#define UNLINK_DYN_RULE(prev, head, q) { \ +#define UNLINK_DYN_RULE(prev, head, q) \ +{ \ ipfw_dyn_rule *old_q = q; \ + struct ipfw_flow_id *id = &q->id; \ + struct thread *td = curthread; \ + struct sockaddr_in lsin; \ + struct sockaddr_in rsin; \ + int error = 0; \ \ /* remove a refcount to the parent */ \ if (q->dyn_type == O_LIMIT) \ q->parent->count--; \ - DEB(printf("ipfw: unlink entry 0x%08x %d -> 0x%08x %d, %d left\n",\ - (q->id.src_ip), (q->id.src_port), \ - (q->id.dst_ip), (q->id.dst_port), dyn_count-1 ); ) \ - if (prev != NULL) \ - prev->next = q = q->next; \ - else \ - head = q = q->next; \ - dyn_count--; \ - uma_zfree(ipfw_dyn_rule_zone, old_q); } + /*if (q->dyn_type == O_AUDIT) { */ \ + AUDIT_PFIL_ENTER(AUE_PFIL_FLOW_END, td, error); \ + if (error == 0) { \ + AUDIT_ARG(text, "ipfw"); \ + addr_port_to_sin(id->src_ip, id->src_port, &lsin); \ + addr_port_to_sin(id->dst_ip, id->dst_port, &rsin); \ + AUDIT_ARG(socket_ex, AF_INET, SOCK_STREAM, \ + (struct sockaddr *)&lsin, (struct sockaddr *)&rsin); \ + } \ + /*}*/ \ + if (!error) { \ + DEB(printf( \ + "ipfw: unlink entry 0x%08x %d -> 0x%08x %d, %d left\n", \ + (q->id.src_ip), (q->id.src_port), \ + (q->id.dst_ip), (q->id.dst_port), dyn_count-1 );) \ + if (prev != NULL) \ + prev->next = q = q->next; \ + else \ + head = q = q->next; \ + dyn_count--; \ + uma_zfree(ipfw_dyn_rule_zone, old_q); \ + } \ + AUDIT_PFIL_EXIT(error, td); \ +} \ #define TIME_LEQ(a,b) ((int)((a)-(b)) <= 0) @@ -1153,6 +1185,7 @@ #define MATCH_FORWARD 1 #define MATCH_NONE 2 #define MATCH_UNKNOWN 3 + int i, dir = MATCH_NONE; ipfw_dyn_rule *prev, *q=NULL; @@ -1224,21 +1257,13 @@ #define BOTH_SYN (TH_SYN | (TH_SYN << 8)) #define BOTH_FIN (TH_FIN | (TH_FIN << 8)) q->state |= (dir == MATCH_FORWARD ) ? flags : (flags << 8); + switch (q->state) { case TH_SYN: /* opening */ q->expire = time_uptime + dyn_syn_lifetime; break; case BOTH_SYN: /* move to established */ - if (IS_IP6_FLOW_ID(pkt)) { - AUDIT_CALL(audit_ipfw_flow6_begin(&pkt->src_ip6, - pkt->src_port, &pkt->dst_ip6, - pkt->dst_port, 0)); - } else { - AUDIT_CALL(audit_ipfw_flow4_begin(pkt->src_ip, - pkt->src_port, pkt->dst_ip, pkt->dst_port, - 0)); - } case BOTH_SYN | TH_FIN : /* one side tries to close */ case BOTH_SYN | (TH_FIN << 8) : if (tcp) { @@ -1349,23 +1374,42 @@ static ipfw_dyn_rule * add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule) { - ipfw_dyn_rule *r; + ipfw_dyn_rule *r = NULL; + struct thread *td = curthread; + struct sockaddr_in lsin; + struct sockaddr_in rsin; int i; + int error = 0; IPFW_DYN_LOCK_ASSERT(); + //if (dyn_type == O_AUDIT) + { + AUDIT_PFIL_ENTER(AUE_PFIL_FLOW_BEGIN, td, error); + if (error != 0) + goto done; + AUDIT_ARG(text, "ipfw"); + addr_port_to_sin(id->src_ip, id->src_port, &lsin); + addr_port_to_sin(id->dst_ip, id->dst_port, &rsin); + AUDIT_ARG(socket_ex, AF_INET, SOCK_STREAM, + (struct sockaddr *)&lsin, (struct sockaddr *)&rsin); + } + if (ipfw_dyn_v == NULL || (dyn_count == 0 && dyn_buckets != curr_dyn_buckets)) { realloc_dynamic_table(); - if (ipfw_dyn_v == NULL) - return NULL; /* failed ! */ + if (ipfw_dyn_v == NULL) { + error = ENOMEM; + goto done; + } } i = hash_packet(id); r = uma_zalloc(ipfw_dyn_rule_zone, M_NOWAIT | M_ZERO); if (r == NULL) { printf ("ipfw: sorry cannot allocate state\n"); - return NULL; + error = ENOMEM; + goto done; } /* increase refcount on parent, and set pointer */ @@ -1393,7 +1437,11 @@ dyn_type, (r->id.src_ip), (r->id.src_port), (r->id.dst_ip), (r->id.dst_port), - dyn_count ); ) + dyn_count)); + +done: + //if (dyn_type == O_AUDIT) + AUDIT_PFIL_EXIT(error, td); return r; } @@ -3165,6 +3213,7 @@ &dyn_dir, proto == IPPROTO_TCP ? TCP(ulp) : NULL)) != NULL) { + /* * Found dynamic entry, update stats * and jump to the 'action' part of @@ -3403,18 +3452,12 @@ struct ip_fw *rule, *f, *prev; int l = RULESIZE(input_rule); - if (chain->rules == NULL && input_rule->rulenum != IPFW_DEFAULT_RULE) { - AUDIT_CALL(audit_ipfw_addrule(input_rule->set, - input_rule->rulenum, EINVAL)); + if (chain->rules == NULL && input_rule->rulenum != IPFW_DEFAULT_RULE) return (EINVAL); - } rule = malloc(l, M_IPFW, M_NOWAIT | M_ZERO); - if (rule == NULL) { - AUDIT_CALL(audit_ipfw_addrule(input_rule->set, - input_rule->rulenum, ENOSPC)); + if (rule == NULL) return (ENOSPC); - } bcopy(input_rule, rule, l); @@ -3474,7 +3517,6 @@ 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); @@ -3571,6 +3613,7 @@ del_entry(struct ip_fw_chain *chain, u_int32_t arg) { struct ip_fw *prev = NULL, *rule; + struct thread *td = curthread; u_int16_t rulenum; /* rule or old_set */ u_int8_t cmd, new_set; @@ -3578,18 +3621,13 @@ cmd = (arg >> 24) & 0xff; new_set = (arg >> 16) & 0xff; - if (cmd > 5 || new_set > RESVD_SET) { - AUDIT_CALL(audit_ipfw_delrule(new_set, rulenum, EINVAL)); + if (cmd > 5 || new_set > RESVD_SET) return EINVAL; - } if (cmd == 0 || cmd == 2 || cmd == 5) { - if (rulenum >= IPFW_DEFAULT_RULE) { - AUDIT_CALL(audit_ipfw_delrule(-1, rulenum, EINVAL)); + if (rulenum >= IPFW_DEFAULT_RULE) return EINVAL; - } } else { if (rulenum > RESVD_SET) { /* old_set */ - AUDIT_CALL(audit_ipfw_delrule(rulenum, -1, EINVAL)); return EINVAL; } } @@ -3599,6 +3637,8 @@ chain->reap = NULL; switch (cmd) { case 0: /* delete rules with given number */ + AUDIT_ARG(text, "ipfw: rule=%05u", rulenum); + /* * locate first rule to delete */ @@ -3616,19 +3656,17 @@ flush_rule_ptrs(chain); 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 */ + AUDIT_ARG(text, "ipfw: set=%02u", rulenum); + flush_rule_ptrs(chain); rule = chain->rules; while (rule->rulenum < IPFW_DEFAULT_RULE) { if (rule->set == rulenum) { rule = remove_rule(chain, rule, prev); - AUDIT_CALL(audit_ipfw_delrule(rule->set, - rule->rulenum, 0)); } else { prev = rule; rule = rule->next; @@ -3637,50 +3675,45 @@ break; case 2: /* move rules with given number to new set */ + AUDIT_ARG(text, "ipfw: move rule=%05u, set=%02u", rulenum, + new_set); + rule = chain->rules; 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 */ + AUDIT_ARG(text, "ipfw: move set=%02u, newset=%02u", rulenum, + new_set); + 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 */ + AUDIT_ARG(text, "ipfw: swap set=%02u, set=%02u", rulenum, + new_set); + 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)); } 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; * new_set - given set number. */ + AUDIT_ARG(text, "ipfw: set=%02u, rule=%05u", new_set, rulenum); + for (; rule->rulenum < rulenum; prev = rule, rule = rule->next) ; if (rule->rulenum != rulenum) { @@ -3691,8 +3724,6 @@ while (rule->rulenum == rulenum) { if (rule->set == new_set) { rule = remove_rule(chain, rule, prev); - AUDIT_CALL(audit_ipfw_delrule(rule->set, - rule->rulenum, 0)); } else { prev = rule; rule = rule->next; @@ -4190,9 +4221,9 @@ { #define RULE_MAXSIZE (256*sizeof(u_int32_t)) int error; - int set; size_t size; struct ip_fw *buf, *rule; + struct thread *td = curthread; u_int32_t rulenum[2]; error = priv_check(sopt->sopt_td, PRIV_NETINET_IPFW); @@ -4254,15 +4285,18 @@ * the old list without the need for a lock. */ - IPFW_WLOCK(&layer3_chain); - layer3_chain.reap = NULL; - free_chain(&layer3_chain, 0 /* keep default rule */); - rule = layer3_chain.reap; - layer3_chain.reap = NULL; - IPFW_WUNLOCK(&layer3_chain); - if (rule != NULL) - reap_rules(rule); - AUDIT_CALL(audit_ipfw_flush(error)); + AUDIT_PFIL_ENTER(AUE_PFIL_POLICY_FLUSH, td, error); + if (error == 0) { + IPFW_WLOCK(&layer3_chain); + layer3_chain.reap = NULL; + free_chain(&layer3_chain, 0 /* keep default rule */); + rule = layer3_chain.reap; + layer3_chain.reap = NULL; + IPFW_WUNLOCK(&layer3_chain); + if (rule != NULL) + reap_rules(rule); + } + AUDIT_PFIL_EXIT(error, td); break; case IP_FW_ADD: @@ -4272,10 +4306,16 @@ if (error == 0) error = check_ipfw_struct(rule, sopt->sopt_valsize); if (error == 0) { - error = add_rule(&layer3_chain, rule); - size = RULESIZE(rule); - if (!error && sopt->sopt_dir == SOPT_GET) - error = sooptcopyout(sopt, rule, size); + AUDIT_PFIL_ENTER(AUE_PFIL_POLICY_ADDRULE, td, error); + if (error == 0) { + AUDIT_ARG(text, "ipfw: set=%02u, rule=%05u", + rule->set, rule->rulenum); + error = add_rule(&layer3_chain, rule); + size = RULESIZE(rule); + if (!error && sopt->sopt_dir == SOPT_GET) + error = sooptcopyout(sopt, rule, size); + } + AUDIT_PFIL_EXIT(error, td); } free(rule, M_TEMP); break; @@ -4298,26 +4338,26 @@ if (error) break; 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 */ - set_disable = - (set_disable | rulenum[0]) & ~rulenum[1] & - ~(1<<RESVD_SET); /* set RESVD_SET always enabled */ + if (size == sizeof(u_int32_t)) { /* delete or reassign */ + AUDIT_PFIL_ENTER(AUE_PFIL_POLICY_DELRULE, td, error); + if (error == 0) + error = del_entry(&layer3_chain, rulenum[0]); + AUDIT_PFIL_EXIT(error, td); + } else if (size == 2*sizeof(u_int32_t)) { /*set enable/disable*/ + AUDIT_PFIL_ENTER(AUE_PFIL_POLICY_DELRULE, td, error); + if (error == 0) { + u_int32_t new_set_disable; + new_set_disable = + (set_disable | rulenum[0]) & ~rulenum[1] & + ~(1<<RESVD_SET); + /* set RESVD_SET always enabled */ - /* 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_ARG(text, + "ipfw: oldsets=0x%x, newsets=0x%x", + set_disable, new_set_disable); + set_disable = new_set_disable; } - - /* 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)); - } + AUDIT_PFIL_EXIT(error, td); } else error = EINVAL; break; @@ -4343,9 +4383,13 @@ sizeof(ent), sizeof(ent)); if (error) break; - error = add_table_entry(&layer3_chain, ent.tbl, - ent.addr, ent.masklen, ent.value); - AUDIT_CALL(audit_ipfw_addtable(ent.tbl, error)); + AUDIT_PFIL_ENTER(AUE_PFIL_POLICY_ADDTABLE, td, error); + if (error == 0) { + AUDIT_ARG(text, "ipfw: table=%u", ent.tbl); + error = add_table_entry(&layer3_chain, ent.tbl, + ent.addr, ent.masklen, ent.value); + } + AUDIT_PFIL_EXIT(error, td); } break; @@ -4357,9 +4401,13 @@ sizeof(ent), sizeof(ent)); if (error) break; - error = del_table_entry(&layer3_chain, ent.tbl, - ent.addr, ent.masklen); - AUDIT_CALL(audit_ipfw_deltable(ent.tbl, error)); + AUDIT_PFIL_ENTER(AUE_PFIL_POLICY_DELTABLE, td, error); + if (error == 0) { + AUDIT_ARG(text, "ipfw: table=%u", ent.tbl); + error = del_table_entry(&layer3_chain, ent.tbl, + ent.addr, ent.masklen); + } + AUDIT_PFIL_EXIT(error, td); } break; @@ -4371,10 +4419,14 @@ sizeof(tbl), sizeof(tbl)); if (error) break; - IPFW_WLOCK(&layer3_chain); - error = flush_table(&layer3_chain, tbl); - IPFW_WUNLOCK(&layer3_chain); - AUDIT_CALL(audit_ipfw_flushtable(tbl, error)); + AUDIT_PFIL_ENTER(AUE_PFIL_POLICY_FLUSHTABLE, td, error); + if (error == 0) { + AUDIT_ARG(text, "ipfw: table=%u", tbl); + IPFW_WLOCK(&layer3_chain); + error = flush_table(&layer3_chain, tbl); + IPFW_WUNLOCK(&layer3_chain); + } + AUDIT_PFIL_EXIT(error, td); } break; ==== //depot/projects/soc2008/diego-audit/src/sys/netinet/ip_fw_pfil.c#4 (text+ko) ==== @@ -43,6 +43,7 @@ #include <sys/mbuf.h> #include <sys/module.h> #include <sys/kernel.h> +#include <sys/proc.h> #include <sys/socket.h> #include <sys/socketvar.h> #include <sys/sysctl.h> @@ -65,6 +66,7 @@ #include <machine/in_cksum.h> +#include <bsm/audit_kevents.h> #include <security/audit/audit.h> int fw_enable = 1; @@ -526,10 +528,15 @@ static int ipfw_modevent(module_t mod, int type, void *unused) { + struct thread *td = curthread; int err = 0; switch (type) { case MOD_LOAD: + AUDIT_PFIL_ENTER(AUE_PFIL_ENABLE, td, err); + if (err != 0) + break; + if ((err = ipfw_init()) != 0) { printf("ipfw_init() error\n"); break; @@ -544,10 +551,13 @@ break; } #endif - AUDIT_CALL(audit_ipfw_enable(err)); break; case MOD_UNLOAD: + AUDIT_PFIL_ENTER(AUE_PFIL_DISABLE, td, err); + if (err != 0) + break; + if ((err = ipfw_unhook()) > 0) break; #ifdef INET6 @@ -555,13 +565,14 @@ break; #endif ipfw_destroy(); - AUDIT_CALL(audit_ipfw_disable(err)); break; default: return EOPNOTSUPP; break; } + AUDIT_ARG(text, "ipfw"); + AUDIT_PFIL_EXIT(err, td); return err; } ==== //depot/projects/soc2008/diego-audit/src/sys/security/audit/audit.c#7 (text) ==== @@ -298,43 +298,62 @@ * XXXAUDIT: Shouldn't there be logic here to sleep waiting on available * pre_q space, suspending the system call until there is room? */ -struct kaudit_record * -audit_new(int event, struct thread *td) +int +audit_new(struct kaudit_record **arp, int event, struct thread *td, int flags) { struct kaudit_record *ar; int no_record; + char **textp; mtx_lock(&audit_mtx); no_record = (audit_suspended || !audit_enabled); mtx_unlock(&audit_mtx); - if (no_record) - return (NULL); + if (no_record) { + *arp = NULL; + return (0); + } + + if (flags & AR_WAITOK) { + ar = uma_zalloc_arg(audit_record_zone, td, M_WAITOK); + } else if (flags & AR_NOWAIT) { + ar = uma_zalloc_arg(audit_record_zone, td, M_NOWAIT); + if (ar == NULL) + return (ENOMEM); + + /* + * XXXDG: Perhaps we should preallocate other dynamic allocated + * args also. + */ + textp = &ar->k_ar.ar_arg_text; + *textp = malloc(MAXPATHLEN, M_AUDITTEXT, M_NOWAIT); + if (*textp == NULL) { + free(ar, M_AUDITTEXT); + return (ENOMEM); + } + } else + return (EINVAL); - /* - * Note: the number of outstanding uncommitted audit records is - * limited to the number of concurrent threads servicing system calls - * in the kernel. - */ - ar = uma_zalloc_arg(audit_record_zone, td, M_WAITOK); ar->k_ar.ar_event = event; + *arp = ar; mtx_lock(&audit_mtx); audit_pre_q_len++; mtx_unlock(&audit_mtx); - return (ar); + return (0); } /* - * Allocate a new record if preselection allows it. Otherwise, return NULL. + * Allocate a new record if preselection allows it. */ -struct kaudit_record * -audit_begin(int event, struct thread *td) +static int +audit_begin(struct kaudit_record **arp, int event, struct thread *td, int flags) { struct kaudit_record *ar; struct au_mask *aumask; au_class_t class; au_id_t auid; + int error; KASSERT(event != AUE_NULL, ("audit_begin: event == AUE_NULL")); @@ -370,13 +389,16 @@ cv_wait(&audit_fail_cv, &audit_mtx); panic("audit_failing_stop: thread continued"); } - ar = audit_new(event, td); - } else if (audit_pipe_preselect(auid, event, class, AU_PRS_BOTH, 0)) - ar = audit_new(event, td); - else + error = audit_new(&ar, event, td, flags); + } else if (audit_pipe_preselect(auid, event, class, AU_PRS_BOTH, 0)) { + error = audit_new(&ar, event, td, flags); + } else { ar = NULL; + error = 0; + } - return (ar); + *arp = ar; + return (error); } void @@ -484,20 +506,19 @@ } /* - * Check if there's already a record being constructed. If true, save it - * into thread's record queue. + * Save the current thread's record (if there's one) into thread's record queue + * and establish a new record. */ static void -audit_enter(struct thread *td) +audit_enter(struct kaudit_record *ar, struct thread *td) { if (td->td_ar != NULL) TAILQ_INSERT_TAIL(td->td_arq, td->td_ar, k_q); - td->td_ar = NULL; + td->td_ar = ar; } /* - * Check if there were a previous record being constructed. If true, make it - * the current record and remove it from thread's record queue. + * Turn the previous saved record (if there's one) into thread's current record. */ static void audit_exit(struct thread *td) @@ -534,16 +555,9 @@ if (event == AUE_NULL) return; - ar = audit_begin(event, td); - if (ar != NULL) { - /* - * Save the current record into thread's record queue and - * create a new record. - */ - - audit_enter(td); - td->td_ar = ar; - } + (void)audit_begin(&ar, event, td, AR_WAITOK); + if (ar != NULL) + audit_enter(ar, td); } /* @@ -568,29 +582,20 @@ else retval = td->td_retval[0]; - /* - * Commit the current record. Turn the previous saved record into the - * current one. - */ audit_commit(td->td_ar, error, retval); audit_exit(td); } -void +int audit_pfil_enter(unsigned short event, struct thread *td) { struct kaudit_record *ar; + int error; - ar = audit_begin(event, td); - if (ar != NULL) { - /* - * Save the current record into thread's record queue and - * create a new record. - */ - - audit_enter(td); - td->td_ar = ar; - } + error = audit_begin(&ar, event, td, AR_NOWAIT); + if (error == 0 && ar != NULL) + audit_enter(ar, td); + return (error); } void @@ -603,10 +608,6 @@ else retval = 0; - /* - * Commit the current record. Turn the previous saved record into the - * current one. - */ audit_commit(td->td_ar, error, retval); audit_exit(td); } @@ -706,7 +707,7 @@ * Where possible coredump records should contain a pathname and arg32 * (signal) tokens. */ - ar = audit_new(AUE_CORE, td); + (void)audit_new(&ar, AUE_CORE, td, AR_WAITOK); if (path != NULL) { pathp = &ar->k_ar.ar_arg_upath1; *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); ==== //depot/projects/soc2008/diego-audit/src/sys/security/audit/audit_private.h#5 (text) ==== @@ -87,6 +87,12 @@ #define AR_PRESELECT_USER_PIPE 0x00008000U /* + * Flags to indicate which allocation scheme to use for allocating records. + */ +#define AR_WAITOK 0x00000001U +#define AR_NOWAIT 0x00000002U + +/* * Audit data is generated as a stream of struct audit_record structures, * linked by struct kaudit_record, and contain storage for possible audit so * that it will not need to be allocated during the processing of a system @@ -248,11 +254,10 @@ * Functions to manage the allocation, release, and commit of kernel audit * records. */ -void audit_abort(struct kaudit_record *ar); -void audit_commit(struct kaudit_record *ar, int error, - int retval); -struct kaudit_record *audit_new(int event, struct thread *td); -struct kaudit_record *audit_begin(int event, struct thread *td); +void audit_abort(struct kaudit_record *ar); +void audit_commit(struct kaudit_record *ar, int error, int retval); +int audit_new(struct kaudit_record **arp, int event, struct thread *td, + int flags); /* Functions to add arguments to kernel audit records. */ ==== //depot/projects/soc2008/diego-audit/src/sys/security/audit/audit_syscalls.c#2 (text) ==== @@ -93,10 +93,10 @@ * XXXAUDIT: Maybe AUE_AUDIT in the system call context and * special pre-select handling? */ - td->td_ar = audit_new(AUE_NULL, td); + (void)audit_new(&ar, AUE_NULL, td, AR_WAITOK); + td->td_ar = ar; if (td->td_ar == NULL) return (ENOTSUP); - ar = td->td_ar; } if (uap->length > MAX_AUDIT_RECORD_SIZE)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200808170323.m7H3Nrpe032034>