From owner-svn-src-stable@freebsd.org Thu Aug 24 17:25:18 2017 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5742FDE4664; Thu, 24 Aug 2017 17:25:18 +0000 (UTC) (envelope-from will@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 287CC84F85; Thu, 24 Aug 2017 17:25:18 +0000 (UTC) (envelope-from will@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v7OHPHbx094944; Thu, 24 Aug 2017 17:25:17 GMT (envelope-from will@FreeBSD.org) Received: (from will@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v7OHPHf1094942; Thu, 24 Aug 2017 17:25:17 GMT (envelope-from will@FreeBSD.org) Message-Id: <201708241725.v7OHPHf1094942@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: will set sender to will@FreeBSD.org using -f From: Will Andrews Date: Thu, 24 Aug 2017 17:25:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r322848 - in stable/10: etc sys/kern X-SVN-Group: stable-10 X-SVN-Commit-Author: will X-SVN-Commit-Paths: in stable/10: etc sys/kern X-SVN-Commit-Revision: 322848 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 24 Aug 2017 17:25:18 -0000 Author: will Date: Thu Aug 24 17:25:16 2017 New Revision: 322848 URL: https://svnweb.freebsd.org/changeset/base/322848 Log: MFC r278479,278494,278525,278545,278592,279237,280410: This change merges devctl notification for userland coredumps. r278479 (rpaulo): Notify devd(8) when a process crashed. This change implements a notification (via devctl) to userland when the kernel produces coredumps after a process has crashed. devd can then run a specific command to produce a human readable crash report. The command is most usually a helper that runs gdb/lldb commands on the file/coredump pair. It's possible to use this functionality for implementing automatic generation of crash reports. devd(8) will be notified of the full path of the binary that crashed and the full path of the coredump file. r278494 (rpaulo): Sanitise the coredump file names sent to devd. While there, add a sysctl to turn this feature off as requested by kib@. r278525 (rpaulo): Remove a printf and an strlen() from the coredump code. r278545 (rpaulo): Restore the data array in coredump(), but use a different style to calculate the length. r278592 (rpaulo): Remove check against NULL after M_WAITOK. r279237 (kib): Keep a reference on the coredump vnode for vn_fullpath() call. Do it by moving vn_close() after the point where notification is sent. r280410 (rpaulo): Disable coredump_devctl because it could lead to leaking paths to jails. Approved by: re Modified: stable/10/etc/devd.conf stable/10/sys/kern/kern_sig.c Directory Properties: stable/10/ (props changed) Modified: stable/10/etc/devd.conf ============================================================================== --- stable/10/etc/devd.conf Thu Aug 24 16:49:34 2017 (r322847) +++ stable/10/etc/devd.conf Thu Aug 24 17:25:16 2017 (r322848) @@ -324,4 +324,16 @@ notify 100 { action "/usr/sbin/automount -c"; }; +# Handle userland coredumps. +# This commented out handler makes it possible to run an +# automated debugging session after the core dump is generated. +# Replace action with a proper coredump handler, but be aware that +# it will run with elevated privileges. +notify 10 { + match "system" "kernel"; + match "subsystem" "signal"; + match "type" "coredump"; + action "logger $comm $core"; +}; + */ Modified: stable/10/sys/kern/kern_sig.c ============================================================================== --- stable/10/sys/kern/kern_sig.c Thu Aug 24 16:49:34 2017 (r322847) +++ stable/10/sys/kern/kern_sig.c Thu Aug 24 17:25:16 2017 (r322848) @@ -44,10 +44,12 @@ __FBSDID("$FreeBSD$"); #include "opt_procdesc.h" #include +#include #include #include #include #include +#include #include #include #include @@ -183,6 +185,10 @@ static int set_core_nodump_flag = 0; SYSCTL_INT(_kern, OID_AUTO, nodump_coredump, CTLFLAG_RW, &set_core_nodump_flag, 0, "Enable setting the NODUMP flag on coredump files"); +static int coredump_devctl = 0; +SYSCTL_INT(_kern, OID_AUTO, coredump_devctl, CTLFLAG_RW, &coredump_devctl, + 0, "Generate a devctl notification when processes coredump"); + /* * Signal properties and actions. * The array below categorizes the signals and their default actions @@ -3317,6 +3323,24 @@ out: return (0); } +static int +coredump_sanitise_path(const char *path) +{ + size_t i; + + /* + * Only send a subset of ASCII to devd(8) because it + * might pass these strings to sh -c. + */ + for (i = 0; path[i]; i++) + if (!(isalpha(path[i]) || isdigit(path[i])) && + path[i] != '/' && path[i] != '.' && + path[i] != '-') + return (0); + + return (1); +} + /* * Dump a process' core. The main routine does some * policy checking, and creates the name of the coredump; @@ -3338,6 +3362,11 @@ coredump(struct thread *td) char *name; /* name of corefile */ off_t limit; int compress; + char *data = NULL; + char *fullpath, *freepath = NULL; + size_t len; + static const char comm_name[] = "comm="; + static const char core_name[] = "core="; #ifdef COMPRESS_USER_CORES compress = compress_user_cores; @@ -3380,7 +3409,7 @@ restart: vattr.va_nlink != 1) { VOP_UNLOCK(vp, 0); error = EFAULT; - goto close; + goto out; } VOP_UNLOCK(vp, 0); @@ -3425,14 +3454,39 @@ restart: lf.l_type = F_UNLCK; VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_FLOCK); } -close: + + /* + * Notify the userland helper that a process triggered a core dump. + * This allows the helper to run an automated debugging session. + */ + if (error != 0 || coredump_devctl == 0) + goto out; + len = MAXPATHLEN * 2 + sizeof(comm_name) - 1 + + sizeof(' ') + sizeof(core_name) - 1; + data = malloc(len, M_TEMP, M_WAITOK); + if (vn_fullpath_global(td, p->p_textvp, &fullpath, &freepath) != 0) + goto out; + if (!coredump_sanitise_path(fullpath)) + goto out; + snprintf(data, len, "%s%s ", comm_name, fullpath); + free(freepath, M_TEMP); + freepath = NULL; + if (vn_fullpath_global(td, vp, &fullpath, &freepath) != 0) + goto out; + if (!coredump_sanitise_path(fullpath)) + goto out; + strlcat(data, core_name, len); + strlcat(data, fullpath, len); + devctl_notify("kernel", "signal", "coredump", data); +out: error1 = vn_close(vp, FWRITE, cred, td); if (error == 0) error = error1; -out: #ifdef AUDIT audit_proc_coredump(td, name, error); #endif + free(freepath, M_TEMP); + free(data, M_TEMP); free(name, M_TEMP); return (error); }