The branch main has been updated by kevans:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=3ce3b342db7e5c987e5eee039f7b290a3919ca37

commit 3ce3b342db7e5c987e5eee039f7b290a3919ca37
Author:     Kyle Evans <kev...@freebsd.org>
AuthorDate: 2025-07-22 16:49:52 +0000
Commit:     Kyle Evans <kev...@freebsd.org>
CommitDate: 2025-07-26 21:31:42 +0000

    kern: add some better error messages for coredump() failures
    
    After debugging with a user on discord why their process is not
    generating coredumps, it became clear that we can use better error
    messages -- particularly to distinguish between the different EFAULT
    cases.  For those that are denied by system policies, include some
    more specific pointers to the relevant knob.
    
    Reviewed by:    kib
    Differential Revision:  https://reviews.freebsd.org/D51465
---
 sys/kern/kern_ucoredump.c | 57 ++++++++++++++++++++++++++++-------------------
 1 file changed, 34 insertions(+), 23 deletions(-)

diff --git a/sys/kern/kern_ucoredump.c b/sys/kern/kern_ucoredump.c
index a2412bf06441..d425596b5f24 100644
--- a/sys/kern/kern_ucoredump.c
+++ b/sys/kern/kern_ucoredump.c
@@ -51,7 +51,7 @@
 #include <sys/ucoredump.h>
 #include <sys/wait.h>
 
-static int coredump(struct thread *td);
+static int coredump(struct thread *td, const char **);
 
 int compress_user_cores = 0;
 
@@ -135,7 +135,6 @@ void
 sigexit(struct thread *td, int sig)
 {
        struct proc *p = td->td_proc;
-       const char *coreinfo;
        int rv;
        bool logexit;
 
@@ -158,6 +157,8 @@ sigexit(struct thread *td, int sig)
         *     (e.g. via fork()), we won't get a dump at all.
         */
        if (sig_do_core(sig) && thread_single(p, SINGLE_NO_EXIT) == 0) {
+               const char *err = NULL;
+
                p->p_sig = sig;
                /*
                 * Log signals which would cause core dumps
@@ -166,32 +167,34 @@ sigexit(struct thread *td, int sig)
                 * XXX : Todo, as well as euid, write out ruid too
                 * Note that coredump() drops proc lock.
                 */
-               rv = coredump(td);
-               switch (rv) {
-               case 0:
+               rv = coredump(td, &err);
+               if (rv == 0) {
+                       MPASS(err == NULL);
                        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;
+               } else if (err == NULL) {
+                       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 (logexit)
                        log(LOG_INFO,
                            "pid %d (%s), jid %d, uid %d: exited on "
-                           "signal %d%s\n", p->p_pid, p->p_comm,
+                           "signal %d (%s%s)\n", p->p_pid, p->p_comm,
                            p->p_ucred->cr_prison->pr_id,
-                           td->td_ucred->cr_uid,
-                           sig &~ WCOREFLAG, coreinfo);
+                           td->td_ucred->cr_uid, sig &~ WCOREFLAG,
+                           err != NULL ? "no core dump - " : "core dumped",
+                           err != NULL ? err : "");
        } else
                PROC_UNLOCK(p);
        exit1(td, 0, sig);
@@ -207,7 +210,7 @@ sigexit(struct thread *td, int sig)
  * ENOSYS; otherwise it returns the error from the process-specific routine.
  */
 static int
-coredump(struct thread *td)
+coredump(struct thread *td, const char **errmsg)
 {
        struct coredumper *iter, *chosen;
        struct proc *p = td->td_proc;
@@ -221,6 +224,13 @@ coredump(struct thread *td)
        if (!do_coredump || (!sugid_coredump && (p->p_flag & P_SUGID) != 0) ||
            (p->p_flag2 & P2_NOTRACE) != 0) {
                PROC_UNLOCK(p);
+
+               if (!do_coredump)
+                       *errmsg = "denied by kern.coredump";
+               else if ((p->p_flag2 & P2_NOTRACE) != 0)
+                       *errmsg = "process has trace disabled";
+               else
+                       *errmsg = "sugid process denied by kern.sugid_coredump";
                return (EFAULT);
        }
 
@@ -235,6 +245,7 @@ coredump(struct thread *td)
        limit = (off_t)lim_cur(td, RLIMIT_CORE);
        if (limit == 0 || racct_get_available(p, RACCT_CORE) == 0) {
                PROC_UNLOCK(p);
+               *errmsg = "coredumpsize limit is 0";
                return (EFBIG);
        }
 

Reply via email to