Re: [PATCH bpf v2 11/11] selftests/bpf: check if max number of bpf_loop iterations is tracked

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Nov 17, 2023 at 5:34 PM Eduard Zingerman <eddyz87@xxxxxxxxx> wrote:
> +
> +SEC("?raw_tp")
> +__success __log_level(2)
> +/* Check that path visiting every callback function once had been
> + * reached by verifier. Variable 'i' below (stored as r2) serves
> + * as a flag, with each decimal digit corresponding to a callback
> + * visit marker.
> + */
> +__msg("(73) *(u8 *)(r1 +0) = r2          ; R1_w=map_value(off=0,ks=4,vs=2,imm=0) R2_w=111111")
> +int bpf_loop_iter_limit_nested(void *unused)
> +{
> +       struct num_context ctx1 = { .i = 0 };
> +       struct num_context ctx2 = { .i = 0 };
> +       /* Set registers for 'i' and 'p' to get guaranteed asm
> +        * instruction shape for __msg matching.
> +        */
> +       register unsigned i asm("r2");
> +       register __u8 *p asm("r1");

I suspect this is fragile.
The compiler will use r2 for 'i' if 'i' is actually there,
but if it can optimize 'i' and 'p' away the r1 and r2 may be used
for something else.
The "register" keyword is not mandatory. Unlike "volatile".

> +       unsigned a, b;
> +
> +       bpf_loop(1, iter_limit_level1_cb, &ctx1, 0);
> +       bpf_loop(1, iter_limit_level1_cb, &ctx2, 0);
> +       a = ctx1.i;
> +       b = ctx2.i;
> +       i = a * 1000 + b;
> +       /* Force 'ctx1.i' and 'ctx2.i' precise. */
> +       p = &choice_arr[(a % 2 + b % 2) % 2];
> +       /* Make sure that verifier does not visit 'impossible' states:
> +        * enumerate all possible callback visit masks.
> +        */
> +       if (a != 0 && a != 1 && a != 11 && a != 101 && a != 111 &&
> +           b != 0 && b != 1 && b != 11 && b != 101 && b != 111)
> +               asm volatile ("r0 /= 0;" ::: "r0");
> +       /* Instruction for match in __msg spec. */
> +       asm volatile ("*(u8 *)(r1 + 0) = r2;" :: "r"(p), "r"(i) : "memory");

Feels even more fragile. Not sure what gcc will do.
Can 'i' be checked as run-time value ?
If it passes the verifier and after bpf_prog_run the 'i' is equal
to expected value we're good, no?





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux