[DTrace-devel] [PATCH] cg: fix return value of copyin()

Kris Van Hees kris.van.hees at oracle.com
Sat Feb 18 06:41:19 UTC 2023


The copyin() function was returning the resolved alloca pointer rather
than the offset into scratchmem (as it should have).  Now that the
function is correctly marked as returning an alloca-pointer, it needs
to return the native representation of an alloca-pointer, i.e. as an
offset into scratchmem.

Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
 libdtrace/dt_cg.c                             | 12 ++++---
 .../funcs/copyin/tst.copyin-retval-ok.d       | 31 +++++++++++++++++++
 2 files changed, 39 insertions(+), 4 deletions(-)
 create mode 100644 test/unittest/funcs/copyin/tst.copyin-retval-ok.d

diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index 0b8cc80a..cc6ca05c 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -4492,6 +4492,9 @@ dt_cg_subr_copyin(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
 
 	/* Allocate scratch space. */
 	dt_cg_subr_alloca_impl(dnp, size, dlp, drp);
+	/* Push the native alloca value to be used as return value. */
+	dt_cg_push_stack(dnp->dn_reg, dlp, drp);
+	/* Turn it into a proper alloca pointer. */
 	dt_cg_alloca_ptr(dlp, drp, dnp->dn_reg, dnp->dn_reg);
 
 	dt_cg_node(src, dlp, drp);
@@ -4506,16 +4509,17 @@ dt_cg_subr_copyin(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
 	emit(dlp, BPF_CALL_HELPER(dtp->dt_bpfhelper[BPF_FUNC_probe_read_user]));
 	dt_regset_free_args(drp);
 	emit(dlp,  BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_0, 0, lbl_ok));
+	dt_regset_free(drp, BPF_REG_0);
 	dt_cg_probe_error(yypcb, DTRACEFLT_BADADDR, DT_ISREG, src->dn_reg);
+	dt_regset_free(drp, src->dn_reg);
 	emitl(dlp, lbl_badsize,
 		   BPF_NOP());
 	dt_cg_probe_error(yypcb, DTRACEFLT_BADSIZE, DT_ISREG, size->dn_reg);
+	dt_regset_free(drp, size->dn_reg);
 	emitl(dlp, lbl_ok,
 		   BPF_NOP());
-	dt_regset_free(drp, BPF_REG_0);
-
-	dt_regset_free(drp, src->dn_reg);
-	dt_regset_free(drp, size->dn_reg);
+	/* Pop the native alloca value as our value. */
+	dt_cg_pop_stack(dnp->dn_reg, dlp, drp);
 
 	TRACE_REGSET("    subr-copyin:End  ");
 }
diff --git a/test/unittest/funcs/copyin/tst.copyin-retval-ok.d b/test/unittest/funcs/copyin/tst.copyin-retval-ok.d
new file mode 100644
index 00000000..b84e7e16
--- /dev/null
+++ b/test/unittest/funcs/copyin/tst.copyin-retval-ok.d
@@ -0,0 +1,31 @@
+/*
+ * 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: Ensure the alloca()'d pointer return value of copyin() is valid.
+ *
+ * SECTION: Actions and Subroutines/copyin()
+ */
+
+#pragma D option quiet
+#pragma D option destructive
+
+BEGIN
+{
+	system("echo dtrace-copyin-test");
+}
+
+syscall::write:entry
+{
+	((uint8_t *)copyin(arg1, 32))[0];
+	exit(0);
+}
+
+ERROR
+{
+	exit(1);
+}
-- 
2.39.1




More information about the DTrace-devel mailing list