[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <864981e25f0cab42df65f9fedcb06be23badc85b.camel@gmail.com>
Date: Mon, 29 Apr 2024 14:56:29 -0700
From: Eduard Zingerman <eddyz87@...il.com>
To: Xu Kuohai <xukuohai@...weicloud.com>, Andrii Nakryiko
<andrii.nakryiko@...il.com>
Cc: Yonghong Song <yonghong.song@...ux.dev>, bpf@...r.kernel.org,
netdev@...r.kernel.org, linux-security-module@...r.kernel.org,
linux-kselftest@...r.kernel.org, Alexei Starovoitov <ast@...nel.org>,
Andrii Nakryiko <andrii@...nel.org>, Daniel Borkmann
<daniel@...earbox.net>, Martin KaFai Lau <martin.lau@...ux.dev>, Song Liu
<song@...nel.org>, John Fastabend <john.fastabend@...il.com>, KP Singh
<kpsingh@...nel.org>, Stanislav Fomichev <sdf@...gle.com>, Hao Luo
<haoluo@...gle.com>, Jiri Olsa <jolsa@...nel.org>, Matt Bobrowski
<mattbobrowski@...gle.com>, Brendan Jackman <jackmanb@...omium.org>, Paul
Moore <paul@...l-moore.com>, James Morris <jmorris@...ei.org>, "Serge E .
Hallyn" <serge@...lyn.com>, Khadija Kamran <kamrankhadijadj@...il.com>,
Casey Schaufler <casey@...aufler-ca.com>, Ondrej Mosnacek
<omosnace@...hat.com>, Kees Cook <keescook@...omium.org>, John Johansen
<john.johansen@...onical.com>, Lukas Bulwahn <lukas.bulwahn@...il.com>,
Roberto Sassu <roberto.sassu@...wei.com>, Shung-Hsi Yu
<shung-hsi.yu@...e.com>
Subject: Re: [PATCH bpf-next v3 07/11] bpf: Fix a false rejection caused by
AND operation
On Sun, 2024-04-28 at 23:15 +0800, Xu Kuohai wrote:
[...]
> diff --git a/kernel/bpf/tnum.c b/kernel/bpf/tnum.c
> index 9dbc31b25e3d..9d4480a683ca 100644
> --- a/kernel/bpf/tnum.c
> +++ b/kernel/bpf/tnum.c
> @@ -150,6 +150,29 @@ struct tnum tnum_intersect(struct tnum a, struct tnum b)
> return TNUM(v & ~mu, mu);
> }
>
> +/*
> + * Each bit has 3 states: unkown, known 0, known 1. If using x to represent
> + * unknown state, the result of the union of two bits is as follows:
> + *
> + * | x 0 1
> + * -----+------------
> + * x | x x x
> + * 0 | x 0 x
> + * 1 | x x 1
> + *
> + * For tnum a and b, only the bits that are both known 0 or known 1 in a
> + * and b are known in the result of union a and b.
> + */
> +struct tnum tnum_union(struct tnum a, struct tnum b)
> +{
> + u64 v0, v1, mu;
> +
> + mu = a.mask | b.mask; // unkown bits either in a or b
> + v1 = (a.value & b.value) & ~mu; // "known 1" bits in both a and b
> + v0 = (~a.value & ~b.value) & ~mu; // "known 0" bits in both a and b
> + return TNUM(v1, mu | ~(v0 | v1));
> +}
> +
Zero would be represented as {.value=0,.mask=0}, suppose 'b' is zero:
1. mu = a.mask | 0; 2. mu = a.mask;
v1 = (a.value & 0) & ~mu; v1 = 0;
v0 = (~a.value & ~0) & ~mu; v0 = ~a.value & ~mu;
return TNUM(v1, mu | ~(v0 | v1)); return TNUM(v1, mu | ~(v0 | v1));
3. v1 = 0; 4. v1 = 0;
v0 = ~a.value & ~a.mask; v0 = ~a.value & ~a.mask;
return TNUM(v1, a.mask | ~(v0 | v1)); return TNUM(0, a.mask | ~(~a.value & ~a.mask));
5. return TNUM(0, a.mask | a.value)
So ultimately this says that for 1's that we knew
we no longer know if those are 1's.
Which seems to make sense.
Powered by blists - more mailing lists