[DTrace-devel] [PATCH v3 18/19] strings: improve bounds on strlen return value
Kris Van Hees
kris.van.hees at oracle.com
Fri Mar 25 05:23:01 UTC 2022
On Thu, Mar 24, 2022 at 06:24:44PM +0000, Nick Alcock via DTrace-devel wrote:
> Checking for a positive bound rather than a zero one prevents the
> minimum range of the return value of strlen coming out of the verifier
> as -1 (which can cause later problems if the verifier decides it needs a
> non-negative arg).
I propose a different solution (see below) to avoid the confusion of setting
ken to be 1 just to then subtract 1 from it.
> We know the return value from bpf_probe_read_str must be non-negative
> anyway, as the comment in the following line notes: this just teaches
> this to the verifier.
>
> Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
> ---
> bpf/strlen.c | 2 +-
> include/bpf-lib.h | 15 +++++++++++++++
> 2 files changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/bpf/strlen.c b/bpf/strlen.c
> index 71ddbca42f01..e10070c9bdaf 100644
> --- a/bpf/strlen.c
> +++ b/bpf/strlen.c
> @@ -21,7 +21,7 @@ noinline uint64_t dt_strlen(const dt_dctx_t *dctx, const char *str)
> int64_t len;
>
> len = bpf_probe_read_str(tmp, (uint64_t)&STRSZ + 1, str);
> - set_not_neg_bound(len);
> + set_positive_bound(len);
>
> return len - 1; /* bpf_probe_read_str() never returns 0 */
Instead do:
len = bpf_probe_read_str(tmp, (uint64_t)&STRSZ + 1, str) - 1;
set_not_neg_bound(len);
return len;
That accomplishes the same thing and it is valid to subtract 1 from the return
value of bpf_probe_read_str) because that will make an error return code more
negative (and we will map that to a 0 length), or it will give us the correct
string length because bpf_probe_read_str() return value includes the terminating
0-byte.
> }
> diff --git a/include/bpf-lib.h b/include/bpf-lib.h
> index d7078da5c146..1c0d4a0c15cd 100644
> --- a/include/bpf-lib.h
> +++ b/include/bpf-lib.h
> @@ -61,5 +61,20 @@
> : /* no clobbers */ \
> );
>
> +/*
> + * Explicit inline assembler to implement a positive bound check:
> + *
> + * if (var < 1)
> + * var = 1;
> + */
> +#define set_positive_bound(var) \
> + asm ("jsgt %0, 0, 1f\n\t" \
> + "mov %0, 1\n\t" \
> + "1:" \
> + : "+r" (var) \
> + : /* no inputs */ \
> + : /* no clobbers */ \
> + );
> +
Not needed with the alternative above.
> #endif /* BPF_LIB_H */
> --
> 2.35.1.261.g8402f930ba.dirty
>
>
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel
More information about the DTrace-devel
mailing list