[DTrace-devel] [PATCH 03/12] Fix alloca() non-constant size check
Eugene Loh
eugene.loh at oracle.com
Fri Jul 22 17:49:25 UTC 2022
Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
Good enough, I guess, albeit with the usual number of questions.
First, I am not real familiar with the alloca()/scratch stuff. So maybe
Nick wants to take a look.
Specifically, I do not understand the whole "8" thing. (I guess there
is an initial 8-byte padding to represent a NULL pointer. This padding
is so invasive, hard-coded into every access to the scratch area. Might
it have been better placed at the *end* of the scratch area? I don't
know. But, again, this eccentricity is being exposed in so many places
in the code... that magic "8" value is all over the place.)
I don't get why DTRACEOPT_SCRATCHSIZE is not the value of the
scratchsize option, as the name would suggest (at least to me).
Having that "8" included in DTRACEOPT_SCRATCHSIZE also makes me wonder
if these checks are right:
dt_bpf.c:
if (dtp->dt_options[DTRACEOPT_SCRATCHSIZE] > 0)
create_gmap(dtp, "scratchmem", ...);
dt_cg.c:
if (dtp->dt_options[DTRACEOPT_SCRATCHSIZE] > 0)
DT_CG_STORE_MAP_PTR("scratchmem", DCTX_SCRATCHMEM);
As for this specific patch:
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
@@ -4177,8 +4177,8 @@ dt_cg_subr_alloca(dt_node_t *dnp, dt_irlist_t
*dlp, dt_regset_t *drp)
emit(dlp, BPF_ALU64_IMM(BPF_ADD, next, 7));
emit(dlp, BPF_ALU64_IMM(BPF_AND, next, (int) -8));
- emit(dlp, BPF_BRANCH_IMM(BPF_JGT, next, opt_scratchsize + 8,
lbl_err));
+ emit(dlp, BPF_BRANCH_IMM(BPF_JGT, next, opt_scratchsize, lbl_err));
- emit(dlp, BPF_BRANCH_IMM(BPF_JLE, dnp->dn_reg, opt_scratchsize + 8,
+ emit(dlp, BPF_BRANCH_IMM(BPF_JLE, dnp->dn_reg, opt_scratchsize - 8,
lbl_ok));
emitl(dlp, lbl_err,
BPF_NOP());
I can guess why we check dnp->dn_reg, but wouldn't mind an explanation.
E.g., I could also believe that if we have checked that next is
in-bounds, then certainly dnp->dn_reg must also be, making that check
unnecessary. (I could argue to myself that there is an edge case, but
it's probably better for me to ask for explanation.)
@@ -4199,7 +4199,7 @@ dt_cg_subr_bcopy(dt_node_t *dnp, dt_irlist_t *dlp,
dt_regset_t *drp)
dt_node_t *src = dnp->dn_args;
dt_node_t *dst = src->dn_list;
dt_node_t *size = dst->dn_list;
- int maxsize =
yypcb->pcb_hdl->dt_options[DTRACEOPT_SCRATCHSIZE];
+ int maxsize =
yypcb->pcb_hdl->dt_options[DTRACEOPT_SCRATCHSIZE] - 8;
uint_t lbl_badsize = dt_irlist_label(dlp);
uint_t lbl_ok = dt_irlist_label(dlp);
Why is there a maxsize at all? Put another way, why is it used to check
size? Why doesn't the dt_cg_alloca_access_check() that follows the
check suffice?
More information about the DTrace-devel
mailing list