[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