[DTrace-devel] [PATCH] Enforce restrictions on destructive actions when -w is not specified

Kris Van Hees kris.van.hees at oracle.com
Thu Apr 8 00:01:42 PDT 2021


Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
 libdtrace/dt_as.c                             |  3 +++
 libdtrace/dt_bpf.c                            |  9 +++++++++
 libdtrace/dt_cc.c                             |  8 +++++++-
 libdtrace/dt_cg.c                             |  3 +++
 .../actions/freopen/err.freopen-destructive.d | 20 +++++++++++++++++++
 .../actions/freopen/err.freopen-destructive.r |  2 ++
 .../actions/system/err.system-destructive.d   | 20 +++++++++++++++++++
 .../actions/system/err.system-destructive.r   |  2 ++
 8 files changed, 66 insertions(+), 1 deletion(-)
 create mode 100644 test/unittest/actions/freopen/err.freopen-destructive.d
 create mode 100644 test/unittest/actions/freopen/err.freopen-destructive.r
 create mode 100644 test/unittest/actions/system/err.system-destructive.d
 create mode 100644 test/unittest/actions/system/err.system-destructive.r

diff --git a/libdtrace/dt_as.c b/libdtrace/dt_as.c
index ed8cc544..760f281c 100644
--- a/libdtrace/dt_as.c
+++ b/libdtrace/dt_as.c
@@ -366,6 +366,9 @@ fail:
 		 */
 		dp->dtdo_buf[i].off = labels[instr.off] - i - 1;
 	}
+	if (pcb->pcb_stmt != NULL &&
+	    pcb->pcb_stmt->dtsd_clauseflags & DT_CLSFLAG_DESTRUCT)
+		dp->dtdo_flags |= DIFOFLG_DESTRUCTIVE;
 
 	pcb->pcb_asvidx = 0;
 
diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
index 50c7c814..1f31f845 100644
--- a/libdtrace/dt_bpf.c
+++ b/libdtrace/dt_bpf.c
@@ -437,6 +437,7 @@ dt_bpf_load_progs(dtrace_hdl_t *dtp, uint_t cflags)
 	dt_probe_t	*prp;
 	dtrace_difo_t	*dp;
 	dt_ident_t	*idp = dt_dlib_get_func(dtp, "dt_error");
+	dtrace_optval_t	dest_ok = DTRACEOPT_UNSET;
 
 	assert(idp != NULL);
 
@@ -454,6 +455,11 @@ dt_bpf_load_progs(dtrace_hdl_t *dtp, uint_t cflags)
 	idp->di_flags |= DT_IDFLG_CGREG;	/* mark it as inline-ready */
 	dt_bpf_reloc_error_prog(dtp, dp);
 
+	/*
+	 * Determine whether we can allow destructive actions.
+	 */
+	dtrace_getopt(dtp, "destructive", &dest_ok);
+
 	/*
 	 * Now construct all the other programs.
 	 */
@@ -468,6 +474,9 @@ dt_bpf_load_progs(dtrace_hdl_t *dtp, uint_t cflags)
 		dp = dt_program_construct(dtp, prp, cflags, NULL);
 		if (dp == NULL)
 			return -1;
+		if (dp->dtdo_flags & DIFOFLG_DESTRUCTIVE &&
+		    dest_ok == DTRACEOPT_UNSET)
+			return dt_set_errno(dtp, EDT_DESTRUCTIVE);
 
 		fd = dt_bpf_load_prog(dtp, prp, dp, cflags);
 		if (fd < 0)
diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
index 6b719b7c..2798ed5c 100644
--- a/libdtrace/dt_cc.c
+++ b/libdtrace/dt_cc.c
@@ -2287,6 +2287,8 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
 	/*
 	 * Now go through the relocations once more, performing the actual
 	 * work of adding executable code (and relocations) for dependencies.
+	 * We also set the destructive flag on the DIFO if any of the
+	 * dependencies have the flag set.
 	 */
 	len = sdp->dtdo_brelen;
 	rp = sdp->dtdo_breltab;
@@ -2354,6 +2356,9 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
 			idp->di_id = ipc;
 			nrp->dofr_data = idp->di_id;	/* set value */
 
+			if (rdp->dtdo_flags & DIFOFLG_DESTRUCTIVE)
+				dp->dtdo_flags |= DIFOFLG_DESTRUCTIVE;
+
 			continue;
 		default:
 			continue;
@@ -2466,7 +2471,7 @@ dt_link(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
 
 	/*
 	 * Replace the program DIFO instruction buffer, BPF relocation table,
-	 * and variable table with the new versions.
+	 * and variable table with the new versions.  Also copy the DIFO flags.
 	 */
 	dt_free(dtp, dp->dtdo_buf);
 	dp->dtdo_buf = fdp->dtdo_buf;
@@ -2477,6 +2482,7 @@ dt_link(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
 	dt_free(dtp, dp->dtdo_breltab);
 	dp->dtdo_breltab = fdp->dtdo_breltab;
 	dp->dtdo_brelen = fdp->dtdo_brelen;
+	dp->dtdo_flags = fdp->dtdo_flags;
 
 	/*
 	 * Write out the new string table.
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index b232f52b..f111165a 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -786,6 +786,9 @@ dt_cg_clsflags(dt_pcb_t *pcb, dtrace_actkind_t kind, const dt_node_t *dnp)
 {
 	int		*cfp = &pcb->pcb_stmt->dtsd_clauseflags;
 
+	if (DTRACEACT_ISDESTRUCTIVE(kind))
+		*cfp |= DT_CLSFLAG_DESTRUCT;
+
 	if (kind == DTRACEACT_COMMIT) {
 		if (*cfp & DT_CLSFLAG_COMMIT)
 			dnerror(dnp, D_COMM_COMM,
diff --git a/test/unittest/actions/freopen/err.freopen-destructive.d b/test/unittest/actions/freopen/err.freopen-destructive.d
new file mode 100644
index 00000000..5cf24614
--- /dev/null
+++ b/test/unittest/actions/freopen/err.freopen-destructive.d
@@ -0,0 +1,20 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * Licensed under the Universal Permissive License v 1.0 as shown at
+ * http://oss.oracle.com/licenses/upl.
+ */
+
+/*
+ * ASSERTION: freopen() is a destructive action
+ *
+ * SECTION: Actions and Subroutines/freopen()
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+	freopen("/dev/null");
+	exit(0);
+}
diff --git a/test/unittest/actions/freopen/err.freopen-destructive.r b/test/unittest/actions/freopen/err.freopen-destructive.r
new file mode 100644
index 00000000..004c30a9
--- /dev/null
+++ b/test/unittest/actions/freopen/err.freopen-destructive.r
@@ -0,0 +1,2 @@
+-- @@stderr --
+dtrace: could not enable tracing: Destructive actions not allowed
diff --git a/test/unittest/actions/system/err.system-destructive.d b/test/unittest/actions/system/err.system-destructive.d
new file mode 100644
index 00000000..bc487aa4
--- /dev/null
+++ b/test/unittest/actions/system/err.system-destructive.d
@@ -0,0 +1,20 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * Licensed under the Universal Permissive License v 1.0 as shown at
+ * http://oss.oracle.com/licenses/upl.
+ */
+
+/*
+ * ASSERTION: system() is a destructive action
+ *
+ * SECTION: Actions and Subroutines/system()
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+	system("/bin/ls");
+	exit(0);
+}
diff --git a/test/unittest/actions/system/err.system-destructive.r b/test/unittest/actions/system/err.system-destructive.r
new file mode 100644
index 00000000..004c30a9
--- /dev/null
+++ b/test/unittest/actions/system/err.system-destructive.r
@@ -0,0 +1,2 @@
+-- @@stderr --
+dtrace: could not enable tracing: Destructive actions not allowed
-- 
2.28.0




More information about the DTrace-devel mailing list