Page MenuHomeFreeBSD

D51465.id158944.diff
No OneTemporary

D51465.id158944.diff

diff --git a/sys/kern/kern_ucoredump.c b/sys/kern/kern_ucoredump.c
--- a/sys/kern/kern_ucoredump.c
+++ b/sys/kern/kern_ucoredump.c
@@ -34,9 +34,11 @@
* SUCH DAMAGE.
*/
+#define EXTERR_CATEGORY EXTERR_CAT_UCOREDUMP
#include <sys/param.h>
#include <sys/acct.h>
#include <sys/compressor.h>
+#include <sys/exterrvar.h>
#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/lock.h>
@@ -123,6 +125,102 @@
blockcount_wait(&cd->cd_refcount, NULL, "dumpwait", 0);
}
+
+/*
+ * Log signals which would cause core dumps
+ * (Log as LOG_INFO to appease those who don't want
+ * these messages.)
+ * XXX : Todo, as well as euid, write out ruid too
+ * Note that coredump() drops proc lock.
+ */
+static void
+sigexit_log(struct thread *td, int sig, bool logging, int rv)
+{
+ struct proc *p = td->td_proc;
+ const char *comm, *err = NULL;
+ int jid;
+ pid_t pid;
+ uid_t uid;
+ struct kexterr *exterr = NULL;
+
+ pid = p->p_pid;
+ comm = p->p_comm;
+ jid = p->p_ucred->cr_prison->pr_id;
+ uid = td->td_ucred->cr_uid;
+ sig &= ~WCOREFLAG;
+
+ if (rv == 0) {
+ if (logging) {
+ log(LOG_INFO,
+ "pid %d (%s), jid %d, uid %d: exited on "
+ "signal %d (core dumped)\n", pid, comm, jid, uid,
+ sig);
+ }
+
+ return;
+ }
+
+ if ((td->td_pflags2 & TDP2_EXTERR) != 0) {
+ exterr = &td->td_kexterr;
+ } else if (!logging) {
+ /*
+ * If we don't have an extended error to report and we're not
+ * logging, then we'll bail out here. Extended errors may get
+ * tapped out via uprintf() even if they won't be logged.
+ */
+ return;
+ }
+
+ switch (rv) {
+ case EFAULT:
+ err = "bad address";
+ break;
+ case EINVAL:
+ err = "invalild argument";
+ break;
+ case EFBIG:
+ err = "too large";
+ break;
+ default:
+ err = "other error";
+ break;
+ }
+
+ if (exterr == NULL) {
+ MPASS(logging);
+
+ log(LOG_INFO,
+ "pid %d (%s), jid %d, uid %d: exited on "
+ "signal %d (no core dump - %s)\n", p->p_pid, p->p_comm,
+ p->p_ucred->cr_prison->pr_id,
+ td->td_ucred->cr_uid, sig &~ WCOREFLAG,
+ err);
+
+ return;
+ }
+
+ if (exterr->msg == NULL) {
+ uprintf("coredump error - errno %d category %u (src line %u)",
+ exterr->error, exterr->cat, exterr->src_line);
+ } else {
+ /*
+ * Clobber our return-based generic error if we have sometihng
+ * more specific.
+ */
+ err = exterr->msg;
+ uprintf("coredump error - %s (src line %u)\n",
+ exterr->msg, exterr->src_line);
+ }
+
+ if (!logging)
+ return;
+
+ log(LOG_INFO,
+ "pid %d (%s), jid %d, uid %d: exited on "
+ "signal %d (no core dump - %s)\n", pid, comm, jid, uid, sig,
+ err);
+}
+
/*
* Force the current process to exit with the specified signal, dumping core
* if appropriate. We bypass the normal tests for masked and caught signals,
@@ -135,7 +233,6 @@
sigexit(struct thread *td, int sig)
{
struct proc *p = td->td_proc;
- const char *coreinfo;
int rv;
bool logexit;
@@ -158,40 +255,19 @@
* (e.g. via fork()), we won't get a dump at all.
*/
if (sig_do_core(sig) && thread_single(p, SINGLE_NO_EXIT) == 0) {
- p->p_sig = sig;
/*
- * Log signals which would cause core dumps
- * (Log as LOG_INFO to appease those who don't want
- * these messages.)
- * XXX : Todo, as well as euid, write out ruid too
- * Note that coredump() drops proc lock.
+ * We want to collect an exterr, even if the thread hadn't
+ * configured it. This thread will not be returning to
+ * userspace, so this shouldn't cause any problems.
*/
+ td->td_pflags2 = (td->td_pflags2 | TDP2_UEXTERR) & ~TDP2_EXTERR;
+
+ p->p_sig = sig;
rv = coredump(td);
- switch (rv) {
- case 0:
+ if (rv == 0)
sig |= WCOREFLAG;
- coreinfo = " (core dumped)";
- break;
- case EFAULT:
- coreinfo = " (no core dump - bad address)";
- break;
- case EINVAL:
- coreinfo = " (no core dump - invalid argument)";
- break;
- case EFBIG:
- coreinfo = " (no core dump - too large)";
- break;
- default:
- coreinfo = " (no core dump - other error)";
- break;
- }
- if (logexit)
- log(LOG_INFO,
- "pid %d (%s), jid %d, uid %d: exited on "
- "signal %d%s\n", p->p_pid, p->p_comm,
- p->p_ucred->cr_prison->pr_id,
- td->td_ucred->cr_uid,
- sig &~ WCOREFLAG, coreinfo);
+
+ sigexit_log(td, sig, logexit, rv);
} else
PROC_UNLOCK(p);
exit1(td, 0, sig);
@@ -211,6 +287,7 @@
{
struct coredumper *iter, *chosen;
struct proc *p = td->td_proc;
+ const char *errmsg = NULL;
struct rm_priotracker tracker;
off_t limit;
int error, priority;
@@ -221,7 +298,14 @@
if (!do_coredump || (!sugid_coredump && (p->p_flag & P_SUGID) != 0) ||
(p->p_flag2 & P2_NOTRACE) != 0) {
PROC_UNLOCK(p);
- return (EFAULT);
+
+ if (!do_coredump)
+ errmsg = "denied by kern.coredump";
+ else if ((p->p_flag2 & P2_NOTRACE) != 0)
+ errmsg = "process has trace disabled";
+ else
+ errmsg = "sugid denied by kern.sugid_coredump";
+ return (EXTERROR(EFAULT, errmsg));
}
/*
@@ -235,7 +319,8 @@
limit = (off_t)lim_cur(td, RLIMIT_CORE);
if (limit == 0 || racct_get_available(p, RACCT_CORE) == 0) {
PROC_UNLOCK(p);
- return (EFBIG);
+ errmsg = "coredumpsize limit is 0";
+ return (EXTERROR(EFBIG, errmsg));
}
rm_rlock(&coredump_rmlock, &tracker);
diff --git a/sys/sys/exterr_cat.h b/sys/sys/exterr_cat.h
--- a/sys/sys/exterr_cat.h
+++ b/sys/sys/exterr_cat.h
@@ -18,6 +18,7 @@
#define EXTERR_CAT_FUSE 4
#define EXTERR_CAT_INOTIFY 5
#define EXTERR_CAT_GENIO 6
+#define EXTERR_CAT_UCOREDUMP 7
#endif
diff --git a/sys/sys/exterrvar.h b/sys/sys/exterrvar.h
--- a/sys/sys/exterrvar.h
+++ b/sys/sys/exterrvar.h
@@ -34,7 +34,7 @@
#ifdef BLOAT_KERNEL_WITH_EXTERR
#define SET_ERROR_MSG(mmsg) (mmsg)
#else
-#define SET_ERROR_MSG(mmsg) NULL
+#define SET_ERROR_MSG(mmsg) (__builtin_constant_p(mmsg) ? NULL : (mmsg))
#endif
#define _SET_ERROR2(eerror, mmsg, pp1, pp2) \

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 11, 9:43 AM (2 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29534940
Default Alt Text
D51465.id158944.diff (5 KB)

Event Timeline