[DTrace-devel] [PATCH 32/47] Ensure that local variables get a 0 value upon first load
Kris Van Hees
kris.van.hees at oracle.com
Sun May 3 20:17:52 PDT 2020
Local variables are stored on the stack and BPF does not allow loading
from an uninitialized stack location. Since D expects variables to
have value 0 prior to first use, we can just pretend the load happened
and instead emit an instruction storing 0 in the destination register.
Orabug: 31220527
Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
libdtrace/dt_cg.c | 13 +++++++++++--
.../codegen/tst.load_before_store_lvar.d | 19 +++++++++++++++++++
2 files changed, 30 insertions(+), 2 deletions(-)
create mode 100644 test/unittest/codegen/tst.load_before_store_lvar.d
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index 39ba1f6d..60037b9a 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -799,8 +799,17 @@ dt_cg_load_var(dt_node_t *dst, dt_irlist_t *dlp, dt_regset_t *drp)
idp->di_flags |= DT_IDFLG_DIFR;
if (idp->di_flags & DT_IDFLG_LOCAL) { /* local var */
- instr = BPF_LOAD(BPF_DW, dst->dn_reg, BPF_REG_FP,
- DT_STK_LVAR(idp->di_id));
+ /*
+ * If this is the first read for this local variable, we know
+ * the value is 0. This avoids storing an initial 0 value in
+ * the variable's stack location.
+ */
+ if (!(idp->di_flags & DT_IDFLG_DIFW))
+ instr = BPF_MOV_IMM(dst->dn_reg, 0);
+ else
+ instr = BPF_LOAD(BPF_DW, dst->dn_reg, BPF_REG_FP,
+ DT_STK_LVAR(idp->di_id));
+
dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
} else if (idp->di_flags & DT_IDFLG_TLS) { /* TLS var */
dt_regset_xalloc(drp, BPF_REG_1);
diff --git a/test/unittest/codegen/tst.load_before_store_lvar.d b/test/unittest/codegen/tst.load_before_store_lvar.d
new file mode 100644
index 00000000..12bb3565
--- /dev/null
+++ b/test/unittest/codegen/tst.load_before_store_lvar.d
@@ -0,0 +1,19 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2020, 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: Test that a load-before-store pattern for a local variable forces
+ * the local variable to be initialized prior to loading.
+ * FAILURE: If the initialization is not done, the BPF verifier will reject
+ * the program due to reading from an uninitialized stack location.
+ */
+
+BEGIN
+{
+ ++this->x;
+ exit(0);
+}
--
2.26.0
More information about the DTrace-devel
mailing list