summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_sig.c33
-rw-r--r--sys/security/audit/audit.c48
-rw-r--r--sys/security/audit/audit.h1
-rw-r--r--sys/security/audit/audit_bsm.c8
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)) {
OpenPOWER on IntegriCloud