Date: Fri, 5 Dec 2008 07:40:36 +0000 (UTC) From: Kip Macy <kmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r185626 - in user/kmacy/HEAD_fast_multi_xmit/sys/security: audit mac mac_bsdextended Message-ID: <200812050740.mB57earn046762@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kmacy Date: Fri Dec 5 07:40:36 2008 New Revision: 185626 URL: http://svn.freebsd.org/changeset/base/185626 Log: IFC 184756:185625 part 1 Modified: user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit.c user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_arg.c user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_bsm.c user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_bsm_token.c user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_private.h user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_syscalls.c user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_worker.c user/kmacy/HEAD_fast_multi_xmit/sys/security/mac/mac_cred.c (props changed) user/kmacy/HEAD_fast_multi_xmit/sys/security/mac_bsdextended/mac_bsdextended.c user/kmacy/HEAD_fast_multi_xmit/sys/security/mac_bsdextended/ugidfw_system.c (props changed) user/kmacy/HEAD_fast_multi_xmit/sys/security/mac_bsdextended/ugidfw_vnode.c (props changed) Modified: user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit.c Fri Dec 5 05:20:08 2008 (r185625) +++ user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit.c Fri Dec 5 07:40:36 2008 (r185626) @@ -129,8 +129,8 @@ struct mtx audit_mtx; * outstanding in the system. */ struct kaudit_queue audit_q; -int audit_q_len; -int audit_pre_q_len; +size_t audit_q_len; +size_t audit_pre_q_len; /* * Audit queue control settings (minimum free, low/high water marks, etc.) @@ -158,6 +158,48 @@ struct cv audit_watermark_cv; static struct cv audit_fail_cv; /* + * Kernel audit information. This will store the current audit address + * or host information that the kernel will use when it's generating + * audit records. This data is modified by the A_GET{SET}KAUDIT auditon(2) + * command. + */ +static struct auditinfo_addr audit_kinfo; +static struct rwlock audit_kinfo_lock; + +#define KINFO_LOCK_INIT() rw_init(&audit_kinfo_lock, \ + "audit_kinfo_lock") +#define KINFO_RLOCK() rw_rlock(&audit_kinfo_lock) +#define KINFO_WLOCK() rw_wlock(&audit_kinfo_lock) +#define KINFO_RUNLOCK() rw_runlock(&audit_kinfo_lock) +#define KINFO_WUNLOCK() rw_wunlock(&audit_kinfo_lock) + +void +audit_set_kinfo(struct auditinfo_addr *ak) +{ + + KASSERT(ak->ai_termid.at_type == AU_IPv4 || + ak->ai_termid.at_type == AU_IPv6, + ("audit_set_kinfo: invalid address type")); + + KINFO_WLOCK(); + audit_kinfo = *ak; + KINFO_WUNLOCK(); +} + +void +audit_get_kinfo(struct auditinfo_addr *ak) +{ + + KASSERT(audit_kinfo.ai_termid.at_type == AU_IPv4 || + audit_kinfo.ai_termid.at_type == AU_IPv6, + ("audit_set_kinfo: invalid address type")); + + KINFO_RLOCK(); + *ak = audit_kinfo; + KINFO_RUNLOCK(); +} + +/* * Construct an audit record for the passed thread. */ static int @@ -165,6 +207,7 @@ audit_record_ctor(void *mem, int size, v { struct kaudit_record *ar; struct thread *td; + struct ucred *cred; KASSERT(sizeof(*ar) == size, ("audit_record_ctor: wrong size")); @@ -177,15 +220,16 @@ audit_record_ctor(void *mem, int size, v /* * Export the subject credential. */ - cru2x(td->td_ucred, &ar->k_ar.ar_subj_cred); - ar->k_ar.ar_subj_ruid = td->td_ucred->cr_ruid; - ar->k_ar.ar_subj_rgid = td->td_ucred->cr_rgid; - ar->k_ar.ar_subj_egid = td->td_ucred->cr_groups[0]; - ar->k_ar.ar_subj_auid = td->td_ucred->cr_audit.ai_auid; - ar->k_ar.ar_subj_asid = td->td_ucred->cr_audit.ai_asid; + cred = td->td_ucred; + cru2x(cred, &ar->k_ar.ar_subj_cred); + ar->k_ar.ar_subj_ruid = cred->cr_ruid; + ar->k_ar.ar_subj_rgid = cred->cr_rgid; + ar->k_ar.ar_subj_egid = cred->cr_groups[0]; + ar->k_ar.ar_subj_auid = cred->cr_audit.ai_auid; + ar->k_ar.ar_subj_asid = cred->cr_audit.ai_asid; ar->k_ar.ar_subj_pid = td->td_proc->p_pid; - ar->k_ar.ar_subj_amask = td->td_ucred->cr_audit.ai_mask; - ar->k_ar.ar_subj_term_addr = td->td_ucred->cr_audit.ai_termid; + ar->k_ar.ar_subj_amask = cred->cr_audit.ai_mask; + ar->k_ar.ar_subj_term_addr = cred->cr_audit.ai_termid; return (0); } @@ -241,7 +285,11 @@ audit_init(void) audit_qctrl.aq_bufsz = AQ_BUFSZ; audit_qctrl.aq_minfree = AU_FS_MINFREE; + audit_kinfo.ai_termid.at_type = AU_IPv4; + audit_kinfo.ai_termid.at_addr[0] = INADDR_ANY; + mtx_init(&audit_mtx, "audit_mtx", NULL, MTX_DEF); + KINFO_LOCK_INIT(); cv_init(&audit_worker_cv, "audit_worker_cv"); cv_init(&audit_watermark_cv, "audit_watermark_cv"); cv_init(&audit_fail_cv, "audit_fail_cv"); @@ -585,6 +633,7 @@ audit_proc_coredump(struct thread *td, c { struct kaudit_record *ar; struct au_mask *aumask; + struct ucred *cred; au_class_t class; int ret, sorf; char **pathp; @@ -595,11 +644,12 @@ audit_proc_coredump(struct thread *td, c /* * Make sure we are using the correct preselection mask. */ - auid = td->td_ucred->cr_audit.ai_auid; + cred = td->td_ucred; + auid = cred->cr_audit.ai_auid; if (auid == AU_DEFAUDITID) aumask = &audit_nae_mask; else - aumask = &td->td_ucred->cr_audit.ai_mask; + aumask = &cred->cr_audit.ai_mask; /* * It's possible for coredump(9) generation to fail. Make sure that * we handle this case correctly for preselection. @@ -612,6 +662,7 @@ audit_proc_coredump(struct thread *td, c if (au_preselect(AUE_CORE, class, aumask, sorf) == 0 && audit_pipe_preselect(auid, AUE_CORE, class, sorf, 0) == 0) return; + /* * If we are interested in seeing this audit record, allocate it. * Where possible coredump records should contain a pathname and arg32 Modified: user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_arg.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_arg.c Fri Dec 5 05:20:08 2008 (r185625) +++ user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_arg.c Fri Dec 5 07:40:36 2008 (r185626) @@ -356,6 +356,7 @@ void audit_arg_process(struct proc *p) { struct kaudit_record *ar; + struct ucred *cred; KASSERT(p != NULL, ("audit_arg_process: p == NULL")); @@ -365,13 +366,14 @@ audit_arg_process(struct proc *p) if (ar == NULL) return; - ar->k_ar.ar_arg_auid = p->p_ucred->cr_audit.ai_auid; - ar->k_ar.ar_arg_euid = p->p_ucred->cr_uid; - ar->k_ar.ar_arg_egid = p->p_ucred->cr_groups[0]; - ar->k_ar.ar_arg_ruid = p->p_ucred->cr_ruid; - ar->k_ar.ar_arg_rgid = p->p_ucred->cr_rgid; - ar->k_ar.ar_arg_asid = p->p_ucred->cr_audit.ai_asid; - ar->k_ar.ar_arg_termid_addr = p->p_ucred->cr_audit.ai_termid; + cred = p->p_ucred; + ar->k_ar.ar_arg_auid = cred->cr_audit.ai_auid; + ar->k_ar.ar_arg_euid = cred->cr_uid; + ar->k_ar.ar_arg_egid = cred->cr_groups[0]; + ar->k_ar.ar_arg_ruid = cred->cr_ruid; + ar->k_ar.ar_arg_rgid = cred->cr_rgid; + ar->k_ar.ar_arg_asid = cred->cr_audit.ai_asid; + ar->k_ar.ar_arg_termid_addr = cred->cr_audit.ai_termid; ar->k_ar.ar_arg_pid = p->p_pid; ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID | ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS); Modified: user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_bsm.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_bsm.c Fri Dec 5 05:20:08 2008 (r185625) +++ user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_bsm.c Fri Dec 5 07:40:36 2008 (r185626) @@ -113,13 +113,34 @@ kau_close(struct au_record *rec, struct size_t tot_rec_size; token_t *cur, *hdr, *trail; struct timeval tm; - - tot_rec_size = rec->len + AUDIT_HEADER_SIZE + AUDIT_TRAILER_SIZE; + size_t hdrsize; + struct auditinfo_addr ak; + struct in6_addr *ap; + + audit_get_kinfo(&ak); + hdrsize = 0; + switch (ak.ai_termid.at_type) { + case AU_IPv4: + hdrsize = (ak.ai_termid.at_addr[0] == INADDR_ANY) ? + AUDIT_HEADER_SIZE : AUDIT_HEADER_EX_SIZE(&ak); + break; + case AU_IPv6: + ap = (struct in6_addr *)&ak.ai_termid.at_addr[0]; + hdrsize = (IN6_IS_ADDR_UNSPECIFIED(ap)) ? AUDIT_HEADER_SIZE : + AUDIT_HEADER_EX_SIZE(&ak); + break; + default: + panic("kau_close: invalid address family"); + } + tot_rec_size = rec->len + hdrsize + AUDIT_TRAILER_SIZE; rec->data = malloc(tot_rec_size, M_AUDITBSM, M_WAITOK | M_ZERO); tm.tv_usec = ctime->tv_nsec / 1000; tm.tv_sec = ctime->tv_sec; - hdr = au_to_header32_tm(tot_rec_size, event, 0, tm); + if (hdrsize != AUDIT_HEADER_SIZE) + hdr = au_to_header32_ex_tm(tot_rec_size, event, 0, tm, &ak); + else + hdr = au_to_header32_tm(tot_rec_size, event, 0, tm); TAILQ_INSERT_HEAD(&rec->token_q, hdr, tokens); trail = au_to_trailer(tot_rec_size); @@ -568,7 +589,7 @@ kaudit_to_bsm(struct kaudit_record *kar, tok = au_to_arg32(1, "cmd", ar->ar_arg_cmd); kau_write(rec, tok); } - /* fall thru */ + /* FALLTHROUGH */ case AUE_AUDITON_GETCAR: case AUE_AUDITON_GETCLASS: @@ -641,7 +662,8 @@ kaudit_to_bsm(struct kaudit_record *kar, tok = au_to_arg32(2, "mode", ar->ar_arg_mode); kau_write(rec, tok); } - /* fall through */ + /* FALLTHROUGH */ + case AUE_ACCESS: case AUE_CHDIR: case AUE_CHROOT: @@ -856,7 +878,8 @@ kaudit_to_bsm(struct kaudit_record *kar, tok = au_to_arg32(1, "flags", ar->ar_arg_fflags); kau_write(rec, tok); } - /* fall through */ + /* FALLTHROUGH */ + case AUE_FORK: case AUE_VFORK: if (ARG_IS_VALID(kar, ARG_PID)) { @@ -992,7 +1015,7 @@ kaudit_to_bsm(struct kaudit_record *kar, tok = au_to_text(ar->ar_arg_text); kau_write(rec, tok); } - /* fall through */ + /* FALLTHROUGH */ case AUE_UMOUNT: UPATH1_VNODE1_TOKENS; @@ -1041,7 +1064,7 @@ kaudit_to_bsm(struct kaudit_record *kar, tok = au_to_arg32(3, "mode", ar->ar_arg_mode); kau_write(rec, tok); } - /* fall through */ + /* FALLTHROUGH */ case AUE_OPEN_R: case AUE_OPEN_RT: @@ -1318,6 +1341,8 @@ kaudit_to_bsm(struct kaudit_record *kar, tok = au_to_arg32(3, "mode", ar->ar_arg_mode); kau_write(rec, tok); } + /* FALLTHROUGH */ + case AUE_SHMUNLINK: if (ARG_IS_VALID(kar, ARG_TEXT)) { tok = au_to_text(ar->ar_arg_text); @@ -1351,7 +1376,7 @@ kaudit_to_bsm(struct kaudit_record *kar, tok = au_to_arg32(4, "value", ar->ar_arg_value); kau_write(rec, tok); } - /* fall through */ + /* FALLTHROUGH */ case AUE_SEMUNLINK: if (ARG_IS_VALID(kar, ARG_TEXT)) { Modified: user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_bsm_token.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_bsm_token.c Fri Dec 5 05:20:08 2008 (r185625) +++ user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_bsm_token.c Fri Dec 5 07:40:36 2008 (r185626) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Apple Inc. + * Copyright (c) 2004-2008 Apple Inc. * Copyright (c) 2005 SPARTA, Inc. * All rights reserved. * @@ -29,6 +29,8 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. + * + * P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#72 */ #include <sys/cdefs.h> @@ -71,7 +73,7 @@ __FBSDID("$FreeBSD$"); * text N bytes + 1 terminating NULL byte */ token_t * -au_to_arg32(char n, char *text, u_int32_t v) +au_to_arg32(char n, const char *text, u_int32_t v) { token_t *t; u_char *dptr = NULL; @@ -90,11 +92,10 @@ au_to_arg32(char n, char *text, u_int32_ ADD_STRING(dptr, text, textlen); return (t); - } token_t * -au_to_arg64(char n, char *text, u_int64_t v) +au_to_arg64(char n, const char *text, u_int64_t v) { token_t *t; u_char *dptr = NULL; @@ -113,11 +114,10 @@ au_to_arg64(char n, char *text, u_int64_ ADD_STRING(dptr, text, textlen); return (t); - } token_t * -au_to_arg(char n, char *text, u_int32_t v) +au_to_arg(char n, const char *text, u_int32_t v) { return (au_to_arg32(n, text, v)); @@ -147,8 +147,8 @@ au_to_attr32(struct vnode_au_info *vni) ADD_U_CHAR(dptr, AUT_ATTR32); /* - * Darwin defines the size for the file mode - * as 2 bytes; BSM defines 4 so pad with 0 + * Darwin defines the size for the file mode as 2 bytes; BSM defines + * 4 so pad with 0. */ ADD_U_INT16(dptr, pad0_16); ADD_U_INT16(dptr, vni->vn_mode); @@ -190,8 +190,8 @@ au_to_attr64(struct vnode_au_info *vni) ADD_U_CHAR(dptr, AUT_ATTR64); /* - * Darwin defines the size for the file mode - * as 2 bytes; BSM defines 4 so pad with 0 + * Darwin defines the size for the file mode as 2 bytes; BSM defines + * 4 so pad with 0. */ ADD_U_INT16(dptr, pad0_16); ADD_U_INT16(dptr, vni->vn_mode); @@ -235,7 +235,7 @@ au_to_attr(struct vnode_au_info *vni) * data items (depends on basic unit) */ token_t * -au_to_data(char unit_print, char unit_type, char unit_count, char *p) +au_to_data(char unit_print, char unit_type, char unit_count, const char *p) { token_t *t; u_char *dptr = NULL; @@ -305,7 +305,7 @@ token_t * au_to_groups(int *groups) { - return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t*)groups)); + return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t *)groups)); } /* @@ -352,7 +352,7 @@ au_to_in_addr(struct in_addr *internet_a /* * token ID 1 byte * address type/length 4 bytes - * Address 16 bytes + * address 16 bytes */ token_t * au_to_in_addr_ex(struct in6_addr *internet_addr) @@ -432,8 +432,8 @@ au_to_ipc_perm(struct ipc_perm *perm) ADD_U_CHAR(dptr, AUT_IPC_PERM); /* - * Darwin defines the sizes for ipc_perm members - * as 2 bytes; BSM defines 4 so pad with 0 + * Darwin defines the sizes for ipc_perm members as 2 bytes; BSM + * defines 4 so pad with 0. */ ADD_U_INT16(dptr, pad0); ADD_U_INT16(dptr, perm->uid); @@ -482,7 +482,7 @@ au_to_iport(u_int16_t iport) * data size bytes */ token_t * -au_to_opaque(char *data, u_int16_t bytes) +au_to_opaque(const char *data, u_int16_t bytes) { token_t *t; u_char *dptr = NULL; @@ -504,7 +504,7 @@ au_to_opaque(char *data, u_int16_t bytes * file pathname N bytes + 1 terminating NULL byte */ token_t * -au_to_file(char *file, struct timeval tm) +au_to_file(const char *file, struct timeval tm) { token_t *t; u_char *dptr = NULL; @@ -534,7 +534,7 @@ au_to_file(char *file, struct timeval tm * text N bytes + 1 terminating NULL byte */ token_t * -au_to_text(char *text) +au_to_text(const char *text) { token_t *t; u_char *dptr = NULL; @@ -558,7 +558,7 @@ au_to_text(char *text) * path N bytes + 1 terminating NULL byte */ token_t * -au_to_path(char *text) +au_to_path(const char *text) { token_t *t; u_char *dptr = NULL; @@ -657,7 +657,7 @@ au_to_process(au_id_t auid, uid_t euid, * terminal ID * port ID 4 bytes/8 bytes (32-bit/64-bit value) * address type-len 4 bytes - * machine address 4/16 bytes + * machine address 16 bytes */ token_t * au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, @@ -668,12 +668,12 @@ au_to_process32_ex(au_id_t auid, uid_t e KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6), ("au_to_process32_ex: type %u", (unsigned int)tid->at_type)); - if (tid->at_type == AU_IPv6) - GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * - sizeof(u_int32_t)); + if (tid->at_type == AU_IPv4) + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + + 10 * sizeof(u_int32_t)); else - GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 * - sizeof(u_int32_t)); + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + + 13 * sizeof(u_int32_t)); ADD_U_CHAR(dptr, AUT_PROCESS32_EX); ADD_U_INT32(dptr, auid); @@ -685,10 +685,12 @@ au_to_process32_ex(au_id_t auid, uid_t e ADD_U_INT32(dptr, sid); ADD_U_INT32(dptr, tid->at_port); ADD_U_INT32(dptr, tid->at_type); - if (tid->at_type == AU_IPv6) - ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t)); - else - ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); + ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); + if (tid->at_type == AU_IPv6) { + ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t)); + ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t)); + ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t)); + } return (t); } @@ -831,7 +833,7 @@ kau_to_socket(struct socket_au_info *soi GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) + sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int32_t)); - ADD_U_CHAR(dptr, AU_SOCK_TOKEN); + ADD_U_CHAR(dptr, AUT_SOCKET); /* Coerce the socket type into a short value */ so_type = soi->so_type; ADD_U_INT16(dptr, so_type); @@ -883,7 +885,7 @@ au_to_sock_unix(struct sockaddr_un *so) GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1); - ADD_U_CHAR(dptr, AU_SOCK_UNIX_TOKEN); + ADD_U_CHAR(dptr, AUT_SOCKUNIX); /* BSM token has two bytes for family */ ADD_U_CHAR(dptr, 0); ADD_U_CHAR(dptr, so->sun_family); @@ -925,7 +927,6 @@ au_to_sock_inet32(struct sockaddr_in *so ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t)); return (t); - } token_t * @@ -949,7 +950,6 @@ au_to_sock_inet128(struct sockaddr_in6 * ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t)); return (t); - } token_t * @@ -1040,7 +1040,7 @@ au_to_subject(au_id_t auid, uid_t euid, * terminal ID * port ID 4 bytes/8 bytes (32-bit/64-bit value) * address type/length 4 bytes - * machine address 4/16 bytes + * machine address 16 bytes */ token_t * au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, @@ -1051,11 +1051,12 @@ au_to_subject32_ex(au_id_t auid, uid_t e KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6), ("au_to_subject32_ex: type %u", (unsigned int)tid->at_type)); - if (tid->at_type == AU_IPv6) - GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * + + if (tid->at_type == AU_IPv4) + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 * sizeof(u_int32_t)); else - GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 * + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * sizeof(u_int32_t)); ADD_U_CHAR(dptr, AUT_SUBJECT32_EX); @@ -1068,9 +1069,9 @@ au_to_subject32_ex(au_id_t auid, uid_t e ADD_U_INT32(dptr, sid); ADD_U_INT32(dptr, tid->at_port); ADD_U_INT32(dptr, tid->at_type); - if (tid->at_type == AU_IPv6) + if (tid->at_type == AU_IPv6) ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t)); - else + else ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); return (t); @@ -1083,17 +1084,17 @@ au_to_subject64_ex(au_id_t auid, uid_t e token_t *t; u_char *dptr = NULL; + KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6), + ("au_to_subject64_ex: type %u", (unsigned int)tid->at_type)); + if (tid->at_type == AU_IPv4) GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) + sizeof(u_int64_t) + 2 * sizeof(u_int32_t)); - else if (tid->at_type == AU_IPv6) + else GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) + sizeof(u_int64_t) + 5 * sizeof(u_int32_t)); - else - panic("au_to_subject64_ex: invalid at_type (%d)", - tid->at_type); ADD_U_CHAR(dptr, AUT_SUBJECT64_EX); ADD_U_INT32(dptr, auid); @@ -1124,8 +1125,8 @@ au_to_subject_ex(au_id_t auid, uid_t eui #if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS) /* - * Collects audit information for the current process - * and creates a subject token from it + * Collects audit information for the current process and creates a subject + * token from it. */ token_t * au_to_me(void) @@ -1227,6 +1228,7 @@ au_to_exec_args(char **argv) return (t); } +#endif /* * token ID 1 byte @@ -1234,7 +1236,7 @@ au_to_exec_args(char **argv) * zonename N bytes + 1 terminating NULL byte */ token_t * -au_to_zonename(char *zonename) +au_to_zonename(const char *zonename) { u_char *dptr = NULL; u_int16_t textlen; @@ -1249,6 +1251,7 @@ au_to_zonename(char *zonename) return (t); } +#if !defined(_KERNEL) && !defined(KERNEL) /* * token ID 1 byte * count 4 bytes @@ -1323,6 +1326,53 @@ au_to_header32_tm(int rec_size, au_event return (t); } +/* + * token ID 1 byte + * record byte count 4 bytes + * version # 1 byte [2] + * event type 2 bytes + * event modifier 2 bytes + * address type/length 4 bytes + * machine address 4 bytes/16 bytes (IPv4/IPv6 address) + * seconds of time 4 bytes/8 bytes (32-bit/64-bit value) + * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value) + */ +token_t * +au_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod, + struct timeval tm, struct auditinfo_addr *aia) +{ + token_t *t; + u_char *dptr = NULL; + u_int32_t timems; + au_tid_addr_t *tid; + + tid = &aia->ai_termid; + KASSERT(tid->at_type == AU_IPv4 || tid->at_type == AU_IPv6, + ("au_to_header32_ex_tm: invalid address family")); + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + + sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 * + sizeof(u_int32_t) + tid->at_type); + + ADD_U_CHAR(dptr, AUT_HEADER32_EX); + ADD_U_INT32(dptr, rec_size); + ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM); + ADD_U_INT16(dptr, e_type); + ADD_U_INT16(dptr, e_mod); + + ADD_U_INT32(dptr, tid->at_type); + if (tid->at_type == AU_IPv6) + ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t)); + else + ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); + timems = tm.tv_usec/1000; + /* Add the timestamp */ + ADD_U_INT32(dptr, tm.tv_sec); + ADD_U_INT32(dptr, timems); /* We need time in ms. */ + + return (t); +} + token_t * au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod, struct timeval tm) @@ -1348,6 +1398,63 @@ au_to_header64_tm(int rec_size, au_event return (t); } +#if !defined(KERNEL) && !defined(_KERNEL) +#ifdef HAVE_AUDIT_SYSCALLS +token_t * +au_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod) +{ + struct timeval tm; + struct auditinfo_addr aia; + + if (gettimeofday(&tm, NULL) == -1) + return (NULL); + if (auditon(A_GETKAUDIT, &aia, sizeof(aia)) < 0) { + if (errno != ENOSYS) + return (NULL); + return (au_to_header32_tm(rec_size, e_type, e_mod, tm)); + } + return (au_to_header32_ex_tm(rec_size, e_type, e_mod, tm, &aia)); +} +#endif /* HAVE_AUDIT_SYSCALLS */ + +token_t * +au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod) +{ + struct timeval tm; + + if (gettimeofday(&tm, NULL) == -1) + return (NULL); + return (au_to_header32_tm(rec_size, e_type, e_mod, tm)); +} + +token_t * +au_to_header64(__unused int rec_size, __unused au_event_t e_type, + __unused au_emod_t e_mod) +{ + struct timeval tm; + + if (gettimeofday(&tm, NULL) == -1) + return (NULL); + return (au_to_header64_tm(rec_size, e_type, e_mod, tm)); +} + +token_t * +au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod) +{ + + return (au_to_header32(rec_size, e_type, e_mod)); +} + +#ifdef HAVE_AUDIT_SYSCALLS +token_t * +au_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod) +{ + + return (au_to_header32_ex(rec_size, e_type, e_mod)); +} +#endif /* HAVE_AUDIT_SYSCALLS */ +#endif /* !defined(KERNEL) && !defined(_KERNEL) */ + /* * token ID 1 byte * trailer magic number 2 bytes Modified: user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_private.h ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_private.h Fri Dec 5 05:20:08 2008 (r185625) +++ user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_private.h Fri Dec 5 07:40:36 2008 (r185626) @@ -132,6 +132,7 @@ union auditon_udata { au_qctrl_t au_qctrl; au_stat_t au_stat; au_fstat_t au_fstat; + auditinfo_addr_t au_kau_info; }; struct posix_ipc_perm { @@ -274,8 +275,8 @@ extern struct mtx audit_mtx; extern struct cv audit_watermark_cv; extern struct cv audit_worker_cv; extern struct kaudit_queue audit_q; -extern int audit_q_len; -extern int audit_pre_q_len; +extern size_t audit_q_len; +extern size_t audit_pre_q_len; extern int audit_in_failure; /* @@ -318,6 +319,12 @@ void audit_trigger_init(void); int audit_send_trigger(unsigned int trigger); /* + * Accessor functions to manage global audit state. + */ +void audit_set_kinfo(struct auditinfo_addr *); +void audit_get_kinfo(struct auditinfo_addr *); + +/* * General audit related functions. */ struct kaudit_record *currecord(void); Modified: user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_syscalls.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_syscalls.c Fri Dec 5 05:20:08 2008 (r185625) +++ user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_syscalls.c Fri Dec 5 07:40:36 2008 (r185626) @@ -157,7 +157,7 @@ free_out: int auditon(struct thread *td, struct auditon_args *uap) { - struct ucred *newcred, *oldcred; + struct ucred *cred, *newcred, *oldcred; int error; union auditon_udata udata; struct proc *tp; @@ -321,22 +321,21 @@ auditon(struct thread *td, struct audito PROC_UNLOCK(tp); return (error); } - if (tp->p_ucred->cr_audit.ai_termid.at_type == AU_IPv6) { + cred = tp->p_ucred; + if (cred->cr_audit.ai_termid.at_type == AU_IPv6) { PROC_UNLOCK(tp); return (EINVAL); } - udata.au_aupinfo.ap_auid = - tp->p_ucred->cr_audit.ai_auid; + udata.au_aupinfo.ap_auid = cred->cr_audit.ai_auid; udata.au_aupinfo.ap_mask.am_success = - tp->p_ucred->cr_audit.ai_mask.am_success; + cred->cr_audit.ai_mask.am_success; udata.au_aupinfo.ap_mask.am_failure = - tp->p_ucred->cr_audit.ai_mask.am_failure; + cred->cr_audit.ai_mask.am_failure; udata.au_aupinfo.ap_termid.machine = - tp->p_ucred->cr_audit.ai_termid.at_addr[0]; + cred->cr_audit.ai_termid.at_addr[0]; udata.au_aupinfo.ap_termid.port = - (dev_t)tp->p_ucred->cr_audit.ai_termid.at_port; - udata.au_aupinfo.ap_asid = - tp->p_ucred->cr_audit.ai_asid; + (dev_t)cred->cr_audit.ai_termid.at_port; + udata.au_aupinfo.ap_asid = cred->cr_audit.ai_asid; PROC_UNLOCK(tp); break; @@ -381,25 +380,26 @@ auditon(struct thread *td, struct audito return (ESRCH); if ((tp = pfind(udata.au_aupinfo_addr.ap_pid)) == NULL) return (ESRCH); - udata.au_aupinfo_addr.ap_auid = - tp->p_ucred->cr_audit.ai_auid; + cred = tp->p_ucred; + udata.au_aupinfo_addr.ap_auid = cred->cr_audit.ai_auid; udata.au_aupinfo_addr.ap_mask.am_success = - tp->p_ucred->cr_audit.ai_mask.am_success; + cred->cr_audit.ai_mask.am_success; udata.au_aupinfo_addr.ap_mask.am_failure = - tp->p_ucred->cr_audit.ai_mask.am_failure; - udata.au_aupinfo_addr.ap_termid = - tp->p_ucred->cr_audit.ai_termid; - udata.au_aupinfo_addr.ap_asid = - tp->p_ucred->cr_audit.ai_asid; + cred->cr_audit.ai_mask.am_failure; + udata.au_aupinfo_addr.ap_termid = cred->cr_audit.ai_termid; + udata.au_aupinfo_addr.ap_asid = cred->cr_audit.ai_asid; PROC_UNLOCK(tp); break; case A_GETKAUDIT: - return (ENOSYS); + audit_get_kinfo(&udata.au_kau_info); break; case A_SETKAUDIT: - return (ENOSYS); + if (udata.au_kau_info.ai_termid.at_type != AU_IPv4 && + udata.au_kau_info.ai_termid.at_type != AU_IPv6) + return (EINVAL); + audit_set_kinfo(&udata.au_kau_info); break; case A_SENDTRIGGER: @@ -500,21 +500,23 @@ int getaudit(struct thread *td, struct getaudit_args *uap) { struct auditinfo ai; + struct ucred *cred; int error; - if (jailed(td->td_ucred)) + cred = td->td_ucred; + if (jailed(cred)) return (ENOSYS); error = priv_check(td, PRIV_AUDIT_GETAUDIT); if (error) return (error); - if (td->td_ucred->cr_audit.ai_termid.at_type == AU_IPv6) - return (ERANGE); + if (cred->cr_audit.ai_termid.at_type == AU_IPv6) + return (E2BIG); bzero(&ai, sizeof(ai)); - ai.ai_auid = td->td_ucred->cr_audit.ai_auid; - ai.ai_mask = td->td_ucred->cr_audit.ai_mask; - ai.ai_asid = td->td_ucred->cr_audit.ai_asid; - ai.ai_termid.machine = td->td_ucred->cr_audit.ai_termid.at_addr[0]; - ai.ai_termid.port = td->td_ucred->cr_audit.ai_termid.at_port; + ai.ai_auid = cred->cr_audit.ai_auid; + ai.ai_mask = cred->cr_audit.ai_mask; + ai.ai_asid = cred->cr_audit.ai_asid; + ai.ai_termid.machine = cred->cr_audit.ai_termid.at_addr[0]; + ai.ai_termid.port = cred->cr_audit.ai_termid.at_port; return (copyout(&ai, uap->auditinfo, sizeof(ai))); } Modified: user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_worker.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_worker.c Fri Dec 5 05:20:08 2008 (r185625) +++ user/kmacy/HEAD_fast_multi_xmit/sys/security/audit/audit_worker.c Fri Dec 5 07:40:36 2008 (r185626) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1999-2005 Apple Inc. + * Copyright (c) 1999-2008 Apple Inc. * Copyright (c) 2006-2008 Robert N. M. Watson * All rights reserved. * @@ -78,17 +78,24 @@ static struct proc *audit_thread; /* * audit_cred and audit_vp are the stored credential and vnode to use for - * active audit trail. They are protected by audit_worker_sx, which will be - * held across all I/O and all rotation to prevent them from being replaced - * (rotated) while in use. The audit_file_rotate_wait flag is set when the - * kernel has delivered a trigger to auditd to rotate the trail, and is - * cleared when the next rotation takes place. It is also protected by - * audit_worker_sx. + * active audit trail. They are protected by the audit worker lock, which + * will be held across all I/O and all rotation to prevent them from being + * replaced (rotated) while in use. The audit_file_rotate_wait flag is set + * when the kernel has delivered a trigger to auditd to rotate the trail, and + * is cleared when the next rotation takes place. It is also protected by + * the audit worker lock. */ static int audit_file_rotate_wait; -static struct sx audit_worker_sx; static struct ucred *audit_cred; static struct vnode *audit_vp; +static struct sx audit_worker_lock; + +#define AUDIT_WORKER_LOCK_INIT() sx_init(&audit_worker_lock, \ + "audit_worker_lock"); +#define AUDIT_WORKER_LOCK_ASSERT() sx_assert(&audit_worker_lock, \ + SA_XLOCKED) +#define AUDIT_WORKER_LOCK() sx_xlock(&audit_worker_lock) +#define AUDIT_WORKER_UNLOCK() sx_xunlock(&audit_worker_lock) /* * Write an audit record to a file, performed as the last stage after both @@ -111,7 +118,7 @@ audit_record_write(struct vnode *vp, str struct vattr vattr; long temp; - sx_assert(&audit_worker_sx, SA_LOCKED); /* audit_file_rotate_wait. */ + AUDIT_WORKER_LOCK_ASSERT(); if (vp == NULL) return; @@ -191,7 +198,7 @@ audit_record_write(struct vnode *vp, str */ if ((audit_fstat.af_filesz != 0) && (audit_file_rotate_wait == 0) && (vattr.va_size >= audit_fstat.af_filesz)) { - sx_assert(&audit_worker_sx, SA_XLOCKED); + AUDIT_WORKER_LOCK_ASSERT(); audit_file_rotate_wait = 1; (void)audit_send_trigger(AUDIT_TRIGGER_ROTATE_KERNEL); @@ -300,20 +307,20 @@ audit_worker_process_record(struct kaudi au_event_t event; au_id_t auid; int error, sorf; - int trail_locked; + int locked; /* - * We hold the audit_worker_sx lock over both writes, if there are - * two, so that the two records won't be split across a rotation and - * end up in two different trail files. + * We hold the audit worker lock over both writes, if there are two, + * so that the two records won't be split across a rotation and end + * up in two different trail files. */ if (((ar->k_ar_commit & AR_COMMIT_USER) && (ar->k_ar_commit & AR_PRESELECT_USER_TRAIL)) || (ar->k_ar_commit & AR_PRESELECT_TRAIL)) { - sx_xlock(&audit_worker_sx); - trail_locked = 1; + AUDIT_WORKER_LOCK(); + locked = 1; } else - trail_locked = 0; + locked = 0; /* * First, handle the user record, if any: commit to the system trail @@ -321,7 +328,7 @@ audit_worker_process_record(struct kaudi */ if ((ar->k_ar_commit & AR_COMMIT_USER) && (ar->k_ar_commit & AR_PRESELECT_USER_TRAIL)) { - sx_assert(&audit_worker_sx, SA_XLOCKED); + AUDIT_WORKER_LOCK_ASSERT(); audit_record_write(audit_vp, audit_cred, ar->k_udata, ar->k_ulen); } @@ -360,7 +367,7 @@ audit_worker_process_record(struct kaudi } if (ar->k_ar_commit & AR_PRESELECT_TRAIL) { - sx_assert(&audit_worker_sx, SA_XLOCKED); + AUDIT_WORKER_LOCK_ASSERT(); audit_record_write(audit_vp, audit_cred, bsm->data, bsm->len); } @@ -371,8 +378,8 @@ audit_worker_process_record(struct kaudi kau_free(bsm); out: - if (trail_locked) - sx_xunlock(&audit_worker_sx); + if (locked) + AUDIT_WORKER_UNLOCK(); } /* @@ -453,14 +460,14 @@ audit_rotate_vnode(struct ucred *cred, s * Rotate the vnode/cred, and clear the rotate flag so that we will * send a rotate trigger if the new file fills. */ - sx_xlock(&audit_worker_sx); + AUDIT_WORKER_LOCK(); old_audit_cred = audit_cred; old_audit_vp = audit_vp; audit_cred = cred; audit_vp = vp; audit_file_rotate_wait = 0; audit_enabled = (audit_vp != NULL); - sx_xunlock(&audit_worker_sx); + AUDIT_WORKER_UNLOCK(); /* * If there was an old vnode/credential, close and free. @@ -479,7 +486,7 @@ audit_worker_init(void) { int error; - sx_init(&audit_worker_sx, "audit_worker_sx"); + AUDIT_WORKER_LOCK_INIT(); error = kproc_create(audit_worker, NULL, &audit_thread, RFHIGHPID, *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812050740.mB57earn046762>