diff options
-rw-r--r-- | sys/kern/kern_sig.c | 33 | ||||
-rw-r--r-- | sys/security/audit/audit.c | 48 | ||||
-rw-r--r-- | sys/security/audit/audit.h | 1 | ||||
-rw-r--r-- | sys/security/audit/audit_bsm.c | 8 |
4 files changed, 84 insertions, 6 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 694d145..3b213a6 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -3058,8 +3058,19 @@ coredump(struct thread *td) MPASS((p->p_flag & P_HADTHREADS) == 0 || p->p_singlethread == td); _STOPEVENT(p, S_CORE, 0); + name = expand_name(p->p_comm, td->td_ucred->cr_uid, p->p_pid); + if (name == NULL) { +#ifdef AUDIT + audit_proc_coredump(td, NULL, EINVAL); +#endif + return (EINVAL); + } if (((sugid_coredump == 0) && p->p_flag & P_SUGID) || do_coredump == 0) { PROC_UNLOCK(p); +#ifdef AUDIT + audit_proc_coredump(td, name, EFAULT); +#endif + free(name, M_TEMP); return (EFAULT); } @@ -3073,19 +3084,25 @@ coredump(struct thread *td) */ limit = (off_t)lim_cur(p, RLIMIT_CORE); PROC_UNLOCK(p); - if (limit == 0) + if (limit == 0) { +#ifdef AUDIT + audit_proc_coredump(td, name, EFBIG); +#endif + free(name, M_TEMP); return (EFBIG); + } restart: - name = expand_name(p->p_comm, td->td_ucred->cr_uid, p->p_pid); - if (name == NULL) - return (EINVAL); NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_SYSSPACE, name, td); flags = O_CREAT | FWRITE | O_NOFOLLOW; error = vn_open(&nd, &flags, S_IRUSR | S_IWUSR, NULL); - free(name, M_TEMP); - if (error) + if (error) { +#ifdef AUDIT + audit_proc_coredump(td, name, error); +#endif + free(name, M_TEMP); return (error); + } vfslocked = NDHASGIANT(&nd); NDFREE(&nd, NDF_ONLY_PNBUF); vp = nd.ni_vp; @@ -3143,6 +3160,10 @@ close: if (error == 0) error = error1; out: +#ifdef AUDIT + audit_proc_coredump(td, name, error); +#endif + free(name, M_TEMP); VFS_UNLOCK_GIANT(vfslocked); return (error); } diff --git a/sys/security/audit/audit.c b/sys/security/audit/audit.c index 1caf18f..1b4ac87 100644 --- a/sys/security/audit/audit.c +++ b/sys/security/audit/audit.c @@ -573,3 +573,51 @@ audit_thread_free(struct thread *td) KASSERT(td->td_ar == NULL, ("audit_thread_free: td_ar != NULL")); } + +void +audit_proc_coredump(struct thread *td, char *path, int errcode) +{ + struct kaudit_record *ar; + struct au_mask *aumask; + au_class_t class; + int ret, sorf; + char **pathp; + au_id_t auid; + + /* + * Make sure we are using the correct preselection mask. + */ + auid = td->td_ucred->cr_audit.ai_auid; + if (auid == AU_DEFAUDITID) + aumask = &audit_nae_mask; + else + aumask = &td->td_ucred->cr_audit.ai_mask; + /* + * It's possible for coredump(9) generation to fail. Make sure that + * we handle this case correctly for preselection. + */ + if (errcode != 0) + sorf = AU_PRS_FAILURE; + else + sorf = AU_PRS_SUCCESS; + class = au_event_class(AUE_CORE); + if (au_preselect(AUE_CORE, class, aumask, sorf) == 0) + return; + /* + * If we are interested in seeing this audit record, allocate it. + * Where possible coredump records should contain a pathname and arg32 + * (signal) tokens. + */ + ar = audit_new(AUE_CORE, td); + if (path != NULL) { + pathp = &ar->k_ar.ar_arg_upath1; + *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); + canon_path(td, path, *pathp); + ARG_SET_VALID(ar, ARG_UPATH1); + } + ar->k_ar.ar_arg_signum = td->td_proc->p_sig; + ARG_SET_VALID(ar, ARG_SIGNUM); + if (errcode != 0) + ret = 1; + audit_commit(ar, errcode, ret); +} diff --git a/sys/security/audit/audit.h b/sys/security/audit/audit.h index 9442a1d..08bebcd 100644 --- a/sys/security/audit/audit.h +++ b/sys/security/audit/audit.h @@ -177,6 +177,7 @@ void audit_cred_destroy(struct ucred *cred); void audit_cred_init(struct ucred *cred); void audit_cred_kproc0(struct ucred *cred); void audit_cred_proc1(struct ucred *cred); +void audit_proc_coredump(struct thread *td, char *path, int errcode); void audit_thread_alloc(struct thread *td); void audit_thread_free(struct thread *td); diff --git a/sys/security/audit/audit_bsm.c b/sys/security/audit/audit_bsm.c index 59f1b86..6ccf66d 100644 --- a/sys/security/audit/audit_bsm.c +++ b/sys/security/audit/audit_bsm.c @@ -715,6 +715,14 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau) UPATH1_VNODE1_TOKENS; break; + case AUE_CORE: + if (ARG_IS_VALID(kar, ARG_SIGNUM)) { + tok = au_to_arg32(0, "signal", ar->ar_arg_signum); + kau_write(rec, tok); + } + UPATH1_VNODE1_TOKENS; + break; + case AUE_EXTATTRCTL: UPATH1_VNODE1_TOKENS; if (ARG_IS_VALID(kar, ARG_CMD)) { |