diff --git a/sys/security/audit/audit.c b/sys/security/audit/audit.c index 44494e8acdf2..c6e17ca6754e 100644 --- a/sys/security/audit/audit.c +++ b/sys/security/audit/audit.c @@ -183,7 +183,7 @@ audit_record_ctor(void *mem, int size, void *arg, int flags) ar->k_ar.ar_subj_asid = td->td_proc->p_au->ai_asid; ar->k_ar.ar_subj_pid = td->td_proc->p_pid; ar->k_ar.ar_subj_amask = td->td_proc->p_au->ai_mask; - ar->k_ar.ar_subj_term = td->td_proc->p_au->ai_termid; + ar->k_ar.ar_subj_term_addr = td->td_proc->p_au->ai_termid; bcopy(td->td_proc->p_comm, ar->k_ar.ar_subj_comm, MAXCOMLEN); PROC_UNLOCK(td->td_proc); diff --git a/sys/security/audit/audit.h b/sys/security/audit/audit.h index a0af12235e27..f0eef65fb458 100644 --- a/sys/security/audit/audit.h +++ b/sys/security/audit/audit.h @@ -87,7 +87,7 @@ extern int audit_suspended; #define ARG_SADDRINET 0x0000000000100000ULL #define ARG_SADDRINET6 0x0000000000200000ULL #define ARG_SADDRUNIX 0x0000000000400000ULL -#define ARG_UNUSED1 0x0000000000800000ULL +#define ARG_TERMID_ADDR 0x0000000000400000ULL #define ARG_UNUSED2 0x0000000001000000ULL #define ARG_UPATH1 0x0000000002000000ULL #define ARG_UPATH2 0x0000000004000000ULL diff --git a/sys/security/audit/audit_arg.c b/sys/security/audit/audit_arg.c index 5147e29df816..9d2e2414bebe 100644 --- a/sys/security/audit/audit_arg.c +++ b/sys/security/audit/audit_arg.c @@ -371,10 +371,10 @@ audit_arg_process(struct proc *p) 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_au->ai_asid; - ar->k_ar.ar_arg_termid = p->p_au->ai_termid; + ar->k_ar.ar_arg_termid_addr = p->p_au->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 | ARG_PID | ARG_PROCESS); + ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS); } void diff --git a/sys/security/audit/audit_bsm.c b/sys/security/audit/audit_bsm.c index c47bd998bce7..5019dd787c02 100644 --- a/sys/security/audit/audit_bsm.c +++ b/sys/security/audit/audit_bsm.c @@ -390,16 +390,40 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau) rec = kau_open(); /* Create the subject token */ - tid.port = ar->ar_subj_term.port; - tid.machine = ar->ar_subj_term.machine; - subj_tok = au_to_subject32(ar->ar_subj_auid, /* audit ID */ - ar->ar_subj_cred.cr_uid, /* eff uid */ - ar->ar_subj_egid, /* eff group id */ - ar->ar_subj_ruid, /* real uid */ - ar->ar_subj_rgid, /* real group id */ - ar->ar_subj_pid, /* process id */ - ar->ar_subj_asid, /* session ID */ - &tid); + switch (ar->ar_subj_term_addr.at_type) { + case AU_IPv4: + tid.port = ar->ar_subj_term_addr.at_port; + tid.machine = ar->ar_subj_term_addr.at_addr[0]; + subj_tok = au_to_subject32(ar->ar_subj_auid, /* audit ID */ + ar->ar_subj_cred.cr_uid, /* eff uid */ + ar->ar_subj_egid, /* eff group id */ + ar->ar_subj_ruid, /* real uid */ + ar->ar_subj_rgid, /* real group id */ + ar->ar_subj_pid, /* process id */ + ar->ar_subj_asid, /* session ID */ + &tid); + break; + case AU_IPv6: + subj_tok = au_to_subject32_ex(ar->ar_subj_auid, + ar->ar_subj_cred.cr_uid, + ar->ar_subj_egid, + ar->ar_subj_ruid, + ar->ar_subj_rgid, + ar->ar_subj_pid, + ar->ar_subj_asid, + &ar->ar_subj_term_addr); + break; + default: + bzero(&tid, sizeof(tid)); + subj_tok = au_to_subject32(ar->ar_subj_auid, + ar->ar_subj_cred.cr_uid, + ar->ar_subj_egid, + ar->ar_subj_ruid, + ar->ar_subj_rgid, + ar->ar_subj_pid, + ar->ar_subj_asid, + &tid); + } /* * The logic inside each case fills in the tokens required for the diff --git a/sys/security/audit/audit_bsm_token.c b/sys/security/audit/audit_bsm_token.c index d5af2dffeab8..f09cc84e483b 100644 --- a/sys/security/audit/audit_bsm_token.c +++ b/sys/security/audit/audit_bsm_token.c @@ -617,6 +617,8 @@ au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, token_t *t; u_char *dptr = NULL; + 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)); @@ -634,12 +636,10 @@ au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, ADD_U_INT32(dptr, sid); ADD_U_INT32(dptr, tid->at_port); ADD_U_INT32(dptr, tid->at_type); - ADD_U_INT32(dptr, tid->at_addr[0]); - if (tid->at_type == AU_IPv6) { - ADD_U_INT32(dptr, tid->at_addr[1]); - ADD_U_INT32(dptr, tid->at_addr[2]); - ADD_U_INT32(dptr, tid->at_addr[3]); - } + 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)); return (t); } @@ -952,6 +952,8 @@ au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, token_t *t; u_char *dptr = NULL; + 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 * sizeof(u_int32_t)); @@ -969,12 +971,10 @@ au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, ADD_U_INT32(dptr, sid); ADD_U_INT32(dptr, tid->at_port); ADD_U_INT32(dptr, tid->at_type); - ADD_U_INT32(dptr, tid->at_addr[0]); - if (tid->at_type == AU_IPv6) { - ADD_U_INT32(dptr, tid->at_addr[1]); - ADD_U_INT32(dptr, tid->at_addr[2]); - ADD_U_INT32(dptr, tid->at_addr[3]); - } + 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)); return (t); } diff --git a/sys/security/audit/audit_private.h b/sys/security/audit/audit_private.h index 660e7c2eda80..fd8a4e9d2206 100644 --- a/sys/security/audit/audit_private.h +++ b/sys/security/audit/audit_private.h @@ -172,6 +172,7 @@ struct audit_record { pid_t ar_subj_asid; /* Audit session ID */ pid_t ar_subj_pid; struct au_tid ar_subj_term; + struct au_tid_addr ar_subj_term_addr; char ar_subj_comm[MAXCOMLEN + 1]; struct au_mask ar_subj_amask; @@ -185,6 +186,7 @@ struct audit_record { pid_t ar_arg_pid; pid_t ar_arg_asid; struct au_tid ar_arg_termid; + struct au_tid_addr ar_arg_termid_addr; uid_t ar_arg_uid; uid_t ar_arg_auid; gid_t ar_arg_gid; diff --git a/sys/security/audit/audit_syscalls.c b/sys/security/audit/audit_syscalls.c index eb62bcf38502..d227334840b0 100644 --- a/sys/security/audit/audit_syscalls.c +++ b/sys/security/audit/audit_syscalls.c @@ -304,14 +304,19 @@ auditon(struct thread *td, struct auditon_args *uap) return (EINVAL); } + if (tp->p_au->ai_termid.at_type == AU_IPv6) { + PROC_UNLOCK(tp); + return (EINVAL); + } udata.au_aupinfo.ap_auid = tp->p_au->ai_auid; udata.au_aupinfo.ap_mask.am_success = tp->p_au->ai_mask.am_success; udata.au_aupinfo.ap_mask.am_failure = tp->p_au->ai_mask.am_failure; udata.au_aupinfo.ap_termid.machine = - tp->p_au->ai_termid.machine; - udata.au_aupinfo.ap_termid.port = tp->p_au->ai_termid.port; + tp->p_au->ai_termid.at_addr[0]; + udata.au_aupinfo.ap_termid.port = + (dev_t)tp->p_au->ai_termid.at_port; udata.au_aupinfo.ap_asid = tp->p_au->ai_asid; PROC_UNLOCK(tp); break; @@ -347,7 +352,18 @@ auditon(struct thread *td, struct auditon_args *uap) break; case A_GETPINFO_ADDR: - return (ENOSYS); + if (udata.au_aupinfo_addr.ap_pid < 1) + return (EINVAL); + if ((tp = pfind(udata.au_aupinfo_addr.ap_pid)) == NULL) + return (EINVAL); + udata.au_aupinfo_addr.ap_auid = tp->p_au->ai_auid; + udata.au_aupinfo_addr.ap_mask.am_success = + tp->p_au->ai_mask.am_success; + udata.au_aupinfo_addr.ap_mask.am_failure = + tp->p_au->ai_mask.am_failure; + udata.au_aupinfo_addr.ap_termid = tp->p_au->ai_termid; + udata.au_aupinfo_addr.ap_asid = tp->p_au->ai_asid; + PROC_UNLOCK(tp); break; case A_GETKAUDIT: @@ -469,7 +485,16 @@ getaudit(struct thread *td, struct getaudit_args *uap) return (error); PROC_LOCK(td->td_proc); - ai = *td->td_proc->p_au; + if (td->td_proc->p_au->ai_termid.at_type == AU_IPv6) { + PROC_UNLOCK(td->td_proc); + return (E2BIG); + } + bzero(&ai, sizeof(ai)); + ai.ai_auid = td->td_proc->p_au->ai_auid; + ai.ai_mask = td->td_proc->p_au->ai_mask; + ai.ai_asid = td->td_proc->p_au->ai_asid; + ai.ai_termid.machine = td->td_proc->p_au->ai_termid.at_addr[0]; + ai.ai_termid.port = td->td_proc->p_au->ai_termid.at_port; PROC_UNLOCK(td->td_proc); return (copyout(&ai, uap->auditinfo, sizeof(ai))); @@ -498,7 +523,13 @@ setaudit(struct thread *td, struct setaudit_args *uap) * XXXRW: Test privilege while holding the proc lock? */ PROC_LOCK(td->td_proc); - *td->td_proc->p_au = ai; + bzero(td->td_proc->p_au, sizeof(struct auditinfo_addr)); + td->td_proc->p_au->ai_auid = ai.ai_auid; + td->td_proc->p_au->ai_mask = ai.ai_mask; + td->td_proc->p_au->ai_asid = ai.ai_asid; + td->td_proc->p_au->ai_termid.at_addr[0] = ai.ai_termid.machine; + td->td_proc->p_au->ai_termid.at_port = ai.ai_termid.port; + td->td_proc->p_au->ai_termid.at_type = AU_IPv4; PROC_UNLOCK(td->td_proc); return (0); @@ -508,6 +539,7 @@ setaudit(struct thread *td, struct setaudit_args *uap) int getaudit_addr(struct thread *td, struct getaudit_addr_args *uap) { + struct auditinfo_addr aia; int error; if (jailed(td->td_ucred)) @@ -515,13 +547,19 @@ getaudit_addr(struct thread *td, struct getaudit_addr_args *uap) error = priv_check(td, PRIV_AUDIT_GETAUDIT); if (error) return (error); - return (ENOSYS); + if (uap->length < sizeof(aia)) + return (EOVERFLOW); + PROC_LOCK(td->td_proc); + aia = *td->td_proc->p_au; + PROC_UNLOCK(td->td_proc); + return (copyout(&aia, uap->auditinfo_addr, sizeof(aia))); } /* ARGSUSED */ int setaudit_addr(struct thread *td, struct setaudit_addr_args *uap) { + struct auditinfo_addr aia; int error; if (jailed(td->td_ucred)) @@ -529,7 +567,14 @@ setaudit_addr(struct thread *td, struct setaudit_addr_args *uap) error = priv_check(td, PRIV_AUDIT_SETAUDIT); if (error) return (error); - return (ENOSYS); + + error = copyin(uap->auditinfo_addr, &aia, sizeof(aia)); + if (error) + return (error); + PROC_LOCK(td->td_proc); + *td->td_proc->p_au = aia; + PROC_UNLOCK(td->td_proc); + return (error); } /* diff --git a/sys/sys/proc.h b/sys/sys/proc.h index a64ff0a853de..72b171e7b5b2 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -579,7 +579,7 @@ struct proc { struct p_sched *p_sched; /* (*) Scheduler-specific data. */ STAILQ_HEAD(, ktr_request) p_ktr; /* (o) KTR event queue. */ LIST_HEAD(, mqueue_notifier) p_mqnotifier; /* (c) mqueue notifiers.*/ - struct auditinfo *p_au; /* (c) Process audit properties. */ + struct auditinfo_addr *p_au; /* (c) Process audit properties. */ }; #define p_session p_pgrp->pg_session