bpf-for-netdev
-----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQTFp0I1jqZrAX+hPRXbK58LschIgwUCZejh3gAKCRDbK58LschI g80KAQCJ0i1CffuizsxQcvC+xrtdZaz1D6L9oE6qJc999zDmKAD/QoipUiWTYKEW KMrX1qoH3LBixoMFEZjSJY6kJWQV3gQ= =Gf2l -----END PGP SIGNATURE----- Merge tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf Daniel Borkmann says: ==================== pull-request: bpf 2024-03-06 We've added 5 non-merge commits during the last 1 day(s) which contain a total of 5 files changed, 77 insertions(+), 4 deletions(-). The main changes are: 1) Fix BPF verifier to check bpf_func_state->callback_depth when pruning states as otherwise unsafe programs could get accepted, from Eduard Zingerman. 2) Fix to zero-initialise xdp_rxq_info struct before running XDP program in CPU map which led to random xdp_md fields, from Toke Høiland-Jørgensen. 3) Fix bonding XDP feature flags calculation when bonding device has no slave devices anymore, from Daniel Borkmann. * tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf: cpumap: Zero-initialise xdp_rxq_info struct before running XDP program selftests/bpf: Fix up xdp bonding test wrt feature flags xdp, bonding: Fix feature flags when there are no slave devs anymore selftests/bpf: test case for callback_depth states pruning logic bpf: check bpf_func_state->callback_depth when pruning states ==================== Link: https://lore.kernel.org/r/20240306220309.13534-1-daniel@iogearbox.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
d3eee81fd6
@ -1811,7 +1811,7 @@ void bond_xdp_set_features(struct net_device *bond_dev)
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
if (!bond_xdp_check(bond)) {
|
||||
if (!bond_xdp_check(bond) || !bond_has_slaves(bond)) {
|
||||
xdp_clear_features_flag(bond_dev);
|
||||
return;
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ static int cpu_map_bpf_prog_run_xdp(struct bpf_cpu_map_entry *rcpu,
|
||||
void **frames, int n,
|
||||
struct xdp_cpumap_stats *stats)
|
||||
{
|
||||
struct xdp_rxq_info rxq;
|
||||
struct xdp_rxq_info rxq = {};
|
||||
struct xdp_buff xdp;
|
||||
int i, nframes = 0;
|
||||
|
||||
|
@ -16602,6 +16602,9 @@ static bool func_states_equal(struct bpf_verifier_env *env, struct bpf_func_stat
|
||||
{
|
||||
int i;
|
||||
|
||||
if (old->callback_depth > cur->callback_depth)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < MAX_BPF_REG; i++)
|
||||
if (!regsafe(env, &old->regs[i], &cur->regs[i],
|
||||
&env->idmap_scratch, exact))
|
||||
|
@ -511,7 +511,7 @@ static void test_xdp_bonding_features(struct skeletons *skeletons)
|
||||
if (!ASSERT_OK(err, "bond bpf_xdp_query"))
|
||||
goto out;
|
||||
|
||||
if (!ASSERT_EQ(query_opts.feature_flags, NETDEV_XDP_ACT_MASK,
|
||||
if (!ASSERT_EQ(query_opts.feature_flags, 0,
|
||||
"bond query_opts.feature_flags"))
|
||||
goto out;
|
||||
|
||||
@ -601,7 +601,7 @@ static void test_xdp_bonding_features(struct skeletons *skeletons)
|
||||
if (!ASSERT_OK(err, "bond bpf_xdp_query"))
|
||||
goto out;
|
||||
|
||||
ASSERT_EQ(query_opts.feature_flags, NETDEV_XDP_ACT_MASK,
|
||||
ASSERT_EQ(query_opts.feature_flags, 0,
|
||||
"bond query_opts.feature_flags");
|
||||
out:
|
||||
bpf_link__destroy(link);
|
||||
|
@ -239,4 +239,74 @@ int bpf_loop_iter_limit_nested(void *unused)
|
||||
return 1000 * a + b + c;
|
||||
}
|
||||
|
||||
struct iter_limit_bug_ctx {
|
||||
__u64 a;
|
||||
__u64 b;
|
||||
__u64 c;
|
||||
};
|
||||
|
||||
static __naked void iter_limit_bug_cb(void)
|
||||
{
|
||||
/* This is the same as C code below, but written
|
||||
* in assembly to control which branches are fall-through.
|
||||
*
|
||||
* switch (bpf_get_prandom_u32()) {
|
||||
* case 1: ctx->a = 42; break;
|
||||
* case 2: ctx->b = 42; break;
|
||||
* default: ctx->c = 42; break;
|
||||
* }
|
||||
*/
|
||||
asm volatile (
|
||||
"r9 = r2;"
|
||||
"call %[bpf_get_prandom_u32];"
|
||||
"r1 = r0;"
|
||||
"r2 = 42;"
|
||||
"r0 = 0;"
|
||||
"if r1 == 0x1 goto 1f;"
|
||||
"if r1 == 0x2 goto 2f;"
|
||||
"*(u64 *)(r9 + 16) = r2;"
|
||||
"exit;"
|
||||
"1: *(u64 *)(r9 + 0) = r2;"
|
||||
"exit;"
|
||||
"2: *(u64 *)(r9 + 8) = r2;"
|
||||
"exit;"
|
||||
:
|
||||
: __imm(bpf_get_prandom_u32)
|
||||
: __clobber_all
|
||||
);
|
||||
}
|
||||
|
||||
SEC("tc")
|
||||
__failure
|
||||
__flag(BPF_F_TEST_STATE_FREQ)
|
||||
int iter_limit_bug(struct __sk_buff *skb)
|
||||
{
|
||||
struct iter_limit_bug_ctx ctx = { 7, 7, 7 };
|
||||
|
||||
bpf_loop(2, iter_limit_bug_cb, &ctx, 0);
|
||||
|
||||
/* This is the same as C code below,
|
||||
* written in assembly to guarantee checks order.
|
||||
*
|
||||
* if (ctx.a == 42 && ctx.b == 42 && ctx.c == 7)
|
||||
* asm volatile("r1 /= 0;":::"r1");
|
||||
*/
|
||||
asm volatile (
|
||||
"r1 = *(u64 *)%[ctx_a];"
|
||||
"if r1 != 42 goto 1f;"
|
||||
"r1 = *(u64 *)%[ctx_b];"
|
||||
"if r1 != 42 goto 1f;"
|
||||
"r1 = *(u64 *)%[ctx_c];"
|
||||
"if r1 != 7 goto 1f;"
|
||||
"r1 /= 0;"
|
||||
"1:"
|
||||
:
|
||||
: [ctx_a]"m"(ctx.a),
|
||||
[ctx_b]"m"(ctx.b),
|
||||
[ctx_c]"m"(ctx.c)
|
||||
: "r1"
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
|
Loading…
x
Reference in New Issue
Block a user