[DTrace-devel] [PATCH] cg, parser: fix handling of alloca()'d string values
Kris Van Hees
kris.van.hees at oracle.com
Sat Feb 18 01:33:00 UTC 2023
When alloca()'d memory is used as a string, special handling is needed
to ensure variable assignment and storing in the output buffer works
correctly.
Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
libdtrace/dt_cg.c | 19 ++++++++++---
libdtrace/dt_parser.c | 10 ++++---
.../actions/printf/tst.conv_s_alloca_var.d | 22 +++++++++++++++
.../actions/printf/tst.conv_s_alloca_var.r | 1 +
.../actions/printf/tst.conv_s_copyin.d | 27 +++++++++++++++++++
.../actions/printf/tst.conv_s_copyin.r | 3 +++
.../actions/printf/tst.conv_s_copyinstr.d | 27 +++++++++++++++++++
.../actions/printf/tst.conv_s_copyinstr.r | 3 +++
.../funcs/bcopy/err.bcopy-into-string.d | 18 +++++++++++++
.../funcs/bcopy/tst.bcopy-into-alloca.d | 21 +++++++++++++++
.../funcs/bcopy/tst.bcopy-into-alloca.r | 1 +
.../bcopy/tst.bcopy-into-string-indirect.d | 21 +++++++++++++++
.../bcopy/tst.bcopy-into-string-indirect.r | 1 +
13 files changed, 166 insertions(+), 8 deletions(-)
create mode 100644 test/unittest/actions/printf/tst.conv_s_alloca_var.d
create mode 100644 test/unittest/actions/printf/tst.conv_s_alloca_var.r
create mode 100644 test/unittest/actions/printf/tst.conv_s_copyin.d
create mode 100644 test/unittest/actions/printf/tst.conv_s_copyin.r
create mode 100644 test/unittest/actions/printf/tst.conv_s_copyinstr.d
create mode 100644 test/unittest/actions/printf/tst.conv_s_copyinstr.r
create mode 100644 test/unittest/funcs/bcopy/err.bcopy-into-string.d
create mode 100644 test/unittest/funcs/bcopy/tst.bcopy-into-alloca.d
create mode 100644 test/unittest/funcs/bcopy/tst.bcopy-into-alloca.r
create mode 100644 test/unittest/funcs/bcopy/tst.bcopy-into-string-indirect.d
create mode 100644 test/unittest/funcs/bcopy/tst.bcopy-into-string-indirect.r
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index 8e767c2f..0b8cc80a 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -1163,7 +1163,7 @@ dt_cg_store_val(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind,
size_t strsize = pcb->pcb_hdl->dt_options[DTRACEOPT_STRSIZE];
if (!not_null)
- dt_cg_check_notnull(dlp, drp, dnp->dn_reg);
+ dt_cg_check_ptr_arg(dlp, drp, dnp, NULL);
TRACE_REGSET("store_val(): Begin ");
off = dt_rec_add(pcb->pcb_hdl, dt_cg_fill_gap, kind, size + 1,
@@ -3009,7 +3009,19 @@ dt_cg_store_var(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp,
srcsz = dt_node_type_size(dnp->dn_right);
size = MIN(srcsz, idp->di_size);
+ dt_cg_check_ptr_arg(dlp, drp, dnp->dn_right, NULL);
dt_cg_memcpy(dlp, drp, reg, dnp->dn_reg, size);
+
+ /*
+ * Since strings are passed by value, we need to force
+ * the value of the assignment to be the destination
+ * address.
+ */
+ if (dt_node_is_string(dnp)) {
+ dt_regset_free(drp, dnp->dn_reg);
+ dnp->dn_reg = reg;
+ } else
+ dt_regset_free(drp, reg);
} else {
size = idp->di_size;
@@ -3017,10 +3029,9 @@ dt_cg_store_var(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp,
(size & (size - 1)) == 0);
emit(dlp, BPF_STORE(ldstw[size], reg, idp->di_offset, dnp->dn_reg));
+ dt_regset_free(drp, reg);
}
- dt_regset_free(drp, reg);
-
TRACE_REGSET(" store_var: End ");
return;
@@ -5412,7 +5423,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
case DT_TOK_STRINGOF:
dt_cg_node(dnp->dn_child, dlp, drp);
- dt_cg_check_ptr_arg(dlp, drp, dnp->dn_child, NULL);
+ dt_cg_check_notnull(dlp, drp, dnp->dn_child->dn_reg);
dnp->dn_reg = dnp->dn_child->dn_reg;
break;
diff --git a/libdtrace/dt_parser.c b/libdtrace/dt_parser.c
index c718680e..e4d6a062 100644
--- a/libdtrace/dt_parser.c
+++ b/libdtrace/dt_parser.c
@@ -3855,11 +3855,13 @@ asgn_common:
lp_idp = lp->dn_ident;
/*
- * Transfer alloca taint. Stores of non-alloca, non-literal-0
- * values turn on DT_IDFLG_NONALLOCA to prevent this identifier
- * from being used for alloca storage anywhere in the program.
+ * Transfer alloca taint unless the value is a string because
+ * those are assigned by value.
+ * Stores of non-alloca, non-literal-0 values turn on
+ * DT_IDFLG_NONALLOCA to prevent this identifier from being
+ * used for alloca storage anywhere in the program.
*/
- if (rp->dn_flags & DT_NF_ALLOCA)
+ if (rp->dn_flags & DT_NF_ALLOCA && !dt_node_is_string(rp))
dt_cook_taint_alloca(lp, lp_idp, rp);
else if (lp_idp && !(rp->dn_kind == DT_NODE_INT && rp->dn_value == 0))
lp_idp->di_flags |= DT_IDFLG_NONALLOCA;
diff --git a/test/unittest/actions/printf/tst.conv_s_alloca_var.d b/test/unittest/actions/printf/tst.conv_s_alloca_var.d
new file mode 100644
index 00000000..7a32cfc5
--- /dev/null
+++ b/test/unittest/actions/printf/tst.conv_s_alloca_var.d
@@ -0,0 +1,22 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2022, 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: The printf action supports '%s' for alloca()'d string variables.
+ *
+ * SECTION: Actions/printf()
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ s = alloca(10);
+ bcopy(probename, s, 5);
+ printf("'%s'", (string)s);
+ exit(0);
+}
diff --git a/test/unittest/actions/printf/tst.conv_s_alloca_var.r b/test/unittest/actions/printf/tst.conv_s_alloca_var.r
new file mode 100644
index 00000000..a1880528
--- /dev/null
+++ b/test/unittest/actions/printf/tst.conv_s_alloca_var.r
@@ -0,0 +1 @@
+'BEGIN'
diff --git a/test/unittest/actions/printf/tst.conv_s_copyin.d b/test/unittest/actions/printf/tst.conv_s_copyin.d
new file mode 100644
index 00000000..11e7745f
--- /dev/null
+++ b/test/unittest/actions/printf/tst.conv_s_copyin.d
@@ -0,0 +1,27 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2022, 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: The printf action supports '%s' for copyin()'d string values.
+ *
+ * SECTION: Actions/printf()
+ */
+/* @@trigger: delaydie */
+
+#pragma D option quiet
+
+syscall::write:entry
+/pid == $target/
+{
+ printf("'%s'", (string)copyin(arg1, 32));
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/test/unittest/actions/printf/tst.conv_s_copyin.r b/test/unittest/actions/printf/tst.conv_s_copyin.r
new file mode 100644
index 00000000..16e2bbcc
--- /dev/null
+++ b/test/unittest/actions/printf/tst.conv_s_copyin.r
@@ -0,0 +1,3 @@
+'Delay in ns needed in delay env '
+-- @@stderr --
+Delay in ns needed in delay env var.
diff --git a/test/unittest/actions/printf/tst.conv_s_copyinstr.d b/test/unittest/actions/printf/tst.conv_s_copyinstr.d
new file mode 100644
index 00000000..ee4f9a79
--- /dev/null
+++ b/test/unittest/actions/printf/tst.conv_s_copyinstr.d
@@ -0,0 +1,27 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2022, 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: The printf action supports '%s' for copyinstr()'d values.
+ *
+ * SECTION: Actions/printf()
+ */
+/* @@trigger: delaydie */
+
+#pragma D option quiet
+
+syscall::write:entry
+/pid == $target/
+{
+ printf("'%s'", copyinstr(arg1, 32));
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/test/unittest/actions/printf/tst.conv_s_copyinstr.r b/test/unittest/actions/printf/tst.conv_s_copyinstr.r
new file mode 100644
index 00000000..7e80ec2d
--- /dev/null
+++ b/test/unittest/actions/printf/tst.conv_s_copyinstr.r
@@ -0,0 +1,3 @@
+'Delay in ns needed in delay env'
+-- @@stderr --
+Delay in ns needed in delay env var.
diff --git a/test/unittest/funcs/bcopy/err.bcopy-into-string.d b/test/unittest/funcs/bcopy/err.bcopy-into-string.d
new file mode 100644
index 00000000..4529a609
--- /dev/null
+++ b/test/unittest/funcs/bcopy/err.bcopy-into-string.d
@@ -0,0 +1,18 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2022, 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: A bcopy() into an alloca()'d string variable yields an error.
+ *
+ * SECTION: Actions and Subroutines/bcopy()
+ */
+
+BEGIN {
+ s = (string)alloca(10);
+ bcopy(probename, s, 5);
+ exit(0);
+}
diff --git a/test/unittest/funcs/bcopy/tst.bcopy-into-alloca.d b/test/unittest/funcs/bcopy/tst.bcopy-into-alloca.d
new file mode 100644
index 00000000..ff57bda6
--- /dev/null
+++ b/test/unittest/funcs/bcopy/tst.bcopy-into-alloca.d
@@ -0,0 +1,21 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2022, 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: A bcopy() into an alloca()'d space can be used as a string.
+ *
+ * SECTION: Actions and Subroutines/bcopy()
+ */
+
+#pragma D option quiet
+
+BEGIN {
+ s = alloca(10);
+ bcopy(probename, s, 5);
+ trace((string)s);
+ exit(0);
+}
diff --git a/test/unittest/funcs/bcopy/tst.bcopy-into-alloca.r b/test/unittest/funcs/bcopy/tst.bcopy-into-alloca.r
new file mode 100644
index 00000000..1bf4c3f4
--- /dev/null
+++ b/test/unittest/funcs/bcopy/tst.bcopy-into-alloca.r
@@ -0,0 +1 @@
+BEGIN
diff --git a/test/unittest/funcs/bcopy/tst.bcopy-into-string-indirect.d b/test/unittest/funcs/bcopy/tst.bcopy-into-string-indirect.d
new file mode 100644
index 00000000..0161e7e2
--- /dev/null
+++ b/test/unittest/funcs/bcopy/tst.bcopy-into-string-indirect.d
@@ -0,0 +1,21 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2022, 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: A bcopy() into an alloca()'d space can be used as a string.
+ *
+ * SECTION: Actions and Subroutines/bcopy()
+ */
+
+#pragma D option quiet
+
+BEGIN {
+ s = alloca(0);
+ bcopy(probename, alloca(10), 5);
+ trace((string)s);
+ exit(0);
+}
diff --git a/test/unittest/funcs/bcopy/tst.bcopy-into-string-indirect.r b/test/unittest/funcs/bcopy/tst.bcopy-into-string-indirect.r
new file mode 100644
index 00000000..1bf4c3f4
--- /dev/null
+++ b/test/unittest/funcs/bcopy/tst.bcopy-into-string-indirect.r
@@ -0,0 +1 @@
+BEGIN
--
2.39.1
More information about the DTrace-devel
mailing list