aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_sig.c
diff options
context:
space:
mode:
authorRui Paulo <rpaulo@FreeBSD.org>2015-02-10 04:34:39 +0000
committerRui Paulo <rpaulo@FreeBSD.org>2015-02-10 04:34:39 +0000
commiteb6368d4f8a065b52cfe6a13c780e940a09db0b7 (patch)
tree3e192fdb94fa4a99d9f5386b90a84f8c36fa75ce /sys/kern/kern_sig.c
parent35994c42c3473d6b9b18d873aa442e4b54f5bb4f (diff)
downloadsrc-eb6368d4f8a065b52cfe6a13c780e940a09db0b7.tar.gz
src-eb6368d4f8a065b52cfe6a13c780e940a09db0b7.zip
Sanitise the coredump file names sent to devd.
While there, add a sysctl to turn this feature off as requested by kib@.
Notes
Notes: svn path=/head/; revision=278494
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r--sys/kern/kern_sig.c55
1 files changed, 39 insertions, 16 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index f25fc16fa6f3..655866d8cee2 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include "opt_core.h"
#include <sys/param.h>
+#include <sys/ctype.h>
#include <sys/systm.h>
#include <sys/signalvar.h>
#include <sys/vnode.h>
@@ -179,6 +180,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 = 1;
+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
@@ -3217,6 +3222,25 @@ out:
return (0);
}
+static int
+coredump_sanitise_path(const char *path)
+{
+ size_t len, i;
+
+ /*
+ * Only send a subset of ASCII to devd(8) because it
+ * might pass these strings to sh -c.
+ */
+ len = strlen(path);
+ for (i = 0; i < len; 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;
@@ -3238,9 +3262,9 @@ coredump(struct thread *td)
void *rl_cookie;
off_t limit;
int compress;
- char *data = NULL;
- size_t len;
+ char data[MAXPATHLEN * 2 + 16]; /* space for devctl notification */
char *fullpath, *freepath = NULL;
+ size_t len;
#ifdef COMPRESS_USER_CORES
compress = compress_user_cores;
@@ -3332,30 +3356,29 @@ close:
* Notify the userland helper that a process triggered a core dump.
* This allows the helper to run an automated debugging session.
*/
- len = MAXPATHLEN * 2 + 5 /* comm= */ + 5 /* core= */ + 1;
- data = malloc(len, M_TEMP, M_NOWAIT);
- if (data == NULL)
+ if (coredump_devctl == 0)
goto out;
if (vn_fullpath_global(td, p->p_textvp, &fullpath, &freepath) != 0)
goto out;
- snprintf(data, len, "comm=%s", fullpath);
- if (freepath != NULL) {
- free(freepath, M_TEMP);
- freepath = NULL;
+ if (!coredump_sanitise_path(fullpath))
+ goto out;
+ snprintf(data, sizeof(data), "comm=%s ", fullpath);
+ free(freepath, M_TEMP);
+ freepath = NULL;
+ if (vn_fullpath_global(td, vp, &fullpath, &freepath) != 0) {
+ printf("could not find coredump\n");
+ goto out;
}
- if (vn_fullpath_global(td, vp, &fullpath, &freepath) != 0)
+ if (!coredump_sanitise_path(fullpath))
goto out;
- snprintf(data, len, "%s core=%s", data, fullpath);
+ strlcat(data, "core=", sizeof(data));
+ len = strlcat(data, fullpath, sizeof(data));
devctl_notify("kernel", "signal", "coredump", data);
- free(name, M_TEMP);
out:
#ifdef AUDIT
audit_proc_coredump(td, name, error);
#endif
- if (freepath != NULL)
- free(freepath, M_TEMP);
- if (data != NULL)
- free(data, M_TEMP);
+ free(freepath, M_TEMP);
free(name, M_TEMP);
return (error);
}