summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2020-11-03 02:10:54 +0000
committerConrad Meyer <cem@FreeBSD.org>2020-11-03 02:10:54 +0000
commiteaa5afcefabc3575437105b54fb31fc74eae4916 (patch)
tree48aaa9f1d2823dc47209bbc812d266f2a77935d2
parent443d8a07dfa3fdd4379b4aac5f76700309d0a454 (diff)
downloadsrc-test2-eaa5afcefabc3575437105b54fb31fc74eae4916.tar.gz
src-test2-eaa5afcefabc3575437105b54fb31fc74eae4916.zip
linux(4) prctl(2): Implement PR_[GS]ET_DUMPABLE
Proxy the flag to the roughly analogous FreeBSD procctl 'TRACE'. TRACE-disabled processes are not coredumped, and Linux !DUMPABLE processes can not be ptraced. There are some additional semantics around ownership of files in the /proc/[pid] pseudo-filesystem, which we do not attempt to emulate correctly at this time. Reviewed by: markj (earlier version) Differential Revision: https://reviews.freebsd.org/D27015
Notes
Notes: svn path=/head/; revision=367290
-rw-r--r--sys/compat/linux/linux_misc.c44
-rw-r--r--sys/compat/linux/linux_misc.h6
2 files changed, 46 insertions, 4 deletions
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 7777b4f04f02..51911342e13a 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -1937,7 +1937,7 @@ linux_prctl(struct thread *td, struct linux_prctl_args *args)
int error = 0, max_size;
struct proc *p = td->td_proc;
char comm[LINUX_MAX_COMM_LEN];
- int pdeath_signal;
+ int pdeath_signal, trace_state;
switch (args->option) {
case LINUX_PR_SET_PDEATHSIG:
@@ -1955,10 +1955,46 @@ linux_prctl(struct thread *td, struct linux_prctl_args *args)
return (copyout(&pdeath_signal,
(void *)(register_t)args->arg2,
sizeof(pdeath_signal)));
+ /*
+ * In Linux, this flag controls if set[gu]id processes can coredump.
+ * There are additional semantics imposed on processes that cannot
+ * coredump:
+ * - Such processes can not be ptraced.
+ * - There are some semantics around ownership of process-related files
+ * in the /proc namespace.
+ *
+ * In FreeBSD, we can (and by default, do) disable setuid coredump
+ * system-wide with 'sugid_coredump.' We control tracability on a
+ * per-process basis with the procctl PROC_TRACE (=> P2_NOTRACE flag).
+ * By happy coincidence, P2_NOTRACE also prevents coredumping. So the
+ * procctl is roughly analogous to Linux's DUMPABLE.
+ *
+ * So, proxy these knobs to the corresponding PROC_TRACE setting.
+ */
+ case LINUX_PR_GET_DUMPABLE:
+ error = kern_procctl(td, P_PID, p->p_pid, PROC_TRACE_STATUS,
+ &trace_state);
+ if (error != 0)
+ return (error);
+ td->td_retval[0] = (trace_state != -1);
+ return (0);
case LINUX_PR_SET_DUMPABLE:
- linux_msg(td, "unsupported prctl PR_SET_DUMPABLE");
- error = EINVAL;
- break;
+ /*
+ * It is only valid for userspace to set one of these two
+ * flags, and only one at a time.
+ */
+ switch (args->arg2) {
+ case LINUX_SUID_DUMP_DISABLE:
+ trace_state = PROC_TRACE_CTL_DISABLE_EXEC;
+ break;
+ case LINUX_SUID_DUMP_USER:
+ trace_state = PROC_TRACE_CTL_ENABLE;
+ break;
+ default:
+ return (EINVAL);
+ }
+ return (kern_procctl(td, P_PID, p->p_pid, PROC_TRACE_CTL,
+ &trace_state));
case LINUX_PR_GET_KEEPCAPS:
/*
* Indicate that we always clear the effective and
diff --git a/sys/compat/linux/linux_misc.h b/sys/compat/linux/linux_misc.h
index 1ee3e8c9b575..c3d9b3719dcf 100644
--- a/sys/compat/linux/linux_misc.h
+++ b/sys/compat/linux/linux_misc.h
@@ -50,6 +50,7 @@
* Second arg is a ptr to return the
* signal.
*/
+#define LINUX_PR_GET_DUMPABLE 3
#define LINUX_PR_SET_DUMPABLE 4
#define LINUX_PR_GET_KEEPCAPS 7 /* Get drop capabilities on setuid */
#define LINUX_PR_SET_KEEPCAPS 8 /* Set drop capabilities on setuid */
@@ -62,6 +63,11 @@
#define LINUX_MAX_COMM_LEN 16 /* Maximum length of the process name. */
+/* For GET/SET DUMPABLE */
+#define LINUX_SUID_DUMP_DISABLE 0 /* Don't coredump setuid processes. */
+#define LINUX_SUID_DUMP_USER 1 /* Dump as user of process. */
+#define LINUX_SUID_DUMP_ROOT 2 /* Dump as root. */
+
#define LINUX_MREMAP_MAYMOVE 1
#define LINUX_MREMAP_FIXED 2