Merge tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf

Pull BPF fixes from Daniel Borkmann:

 - Fix BPF verifier to preserve full pointer state for commuted
   scalar += pointer arithmetic (Yiyang Chen, Eduard Zingerman)

 - Fix a use-after-free of request sockets in the BPF TCP iterator
   batching (Jose Fernandez)

 - Fix a use-after-free of sk_redir in the BPF sockmap send verdict
   path (Chengfeng Ye)

 - Fix a netns reference imbalance in the BPF conntrack kfuncs
   (Chengfeng Ye)

 - Fix bpf_get_fsverity_digest() dynptr assumptions and silent
   digest truncation (Eric Biggers)

 - Fix bpf_tcp_{gen,check}_syncookie to check sk_state before
   sk_protocol to make sure it is a full socket (Luxiao Xu)

 - Fix rqspinlock to reset the tail when preserving the queue
   on deadlock (Kumar Kartikeya Dwivedi)

* tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf:
  rqspinlock: Reset tail when preserving queue on deadlock
  bpf: Check sk_state before sk_protocol in bpf_tcp_*_syncookie
  fsverity: Fix silent truncation in bpf_get_fsverity_digest()
  fsverity: Fix bpf_get_fsverity_digest() dynptr assumptions
  bpf: tcp: Fix use-after-free in bpf_iter_tcp_established_batch()
  bpf: Fix netns reference imbalance in conntrack kfuncs
  bpf, sockmap: Fix sk_redir use-after-free in send verdict
  selftests/bpf: Cover commuted pointer state propagation
  bpf: Propagate untrusted pointer state in commuted arithmetic
  bpf: Preserve pointer state for commuted arithmetic
  bpf: Simplify sanitize_err() signature
This commit is contained in:
Linus Torvalds
2026-08-07 08:08:57 -07:00
10 changed files with 198 additions and 76 deletions

View File

@@ -1635,6 +1635,36 @@ static int callback(__u32 index, void *data)
return 0;
}
/* A commuted add should preserve the parent id of a dynptr data slice. */
SEC("?raw_tp")
__failure __msg("invalid mem access 'scalar'")
int dynptr_slice_commuted_invalidate(void *ctx)
{
struct bpf_dynptr ptr;
__u32 *slice, *derived;
bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(__u32), 0, &ptr);
slice = bpf_dynptr_data(&ptr, 0, sizeof(__u32));
if (!slice)
goto done;
asm volatile ("%[dst] = 0;"
"%[dst] += %[src];"
"%[src] = 0;"
: [dst]"=&r"(derived), [src]"+r"(slice)
:
: "memory");
bpf_ringbuf_discard_dynptr(&ptr, 0);
val = *derived;
return 0;
done:
bpf_ringbuf_discard_dynptr(&ptr, 0);
return 0;
}
/* If the dynptr is written into in a callback function, its data
* slices should be invalidated as well.
*/

View File

@@ -226,4 +226,21 @@ int null_check(void *ctx)
return 0;
}
SEC("socket")
__success
__retval(1)
int ldx_is_ok_commuted_addr(void *ctx)
{
int v, *p, *derived;
v = 1;
p = bpf_rdonly_cast(&v, 0);
asm volatile ("%[dst] = 0;"
"%[dst] += %[src];"
: [dst]"=&r"(derived)
: [src]"r"(p)
: "memory");
return *derived;
}
char _license[] SEC("license") = "GPL";

View File

@@ -97,4 +97,45 @@ __naked void misaligned_read_from_stack(void)
" ::: __clobber_all);
}
SEC("socket")
__description("stack pointer arithmetic preserves frame number")
__failure __msg("R7 invalid mem access 'scalar'")
__naked void stack_ptr_arith_preserves_frameno(void)
{
asm volatile ("\
r3 = 0; \
*(u64 *)(r10 - 8) = r3; \
r1 = %[map_hash_8b] ll; \
r2 = r10; \
r2 += -8; \
call %[bpf_map_lookup_elem]; \
if r0 != 0 goto +2; \
r0 = 0; \
exit; \
r1 = r0; \
r2 = 0; \
r3 = 0; \
call stack_ptr_arith_preserves_frameno_subprog;\
r0 = 0; \
exit; \
":
: __imm(bpf_map_lookup_elem),
__imm_addr(map_hash_8b)
: __clobber_all);
}
static __used __naked void stack_ptr_arith_preserves_frameno_subprog(void)
{
asm volatile ("\
*(u64 *)(r10 - 8) = r1; \
r6 = -8; \
r6 += r10; \
*(u64 *)(r6 + 0) = r2; \
r7 = *(u64 *)(r10 - 8); \
*(u64 *)(r7 + 0) = r3; \
r0 = 0; \
exit; \
"::: __clobber_all);
}
char _license[] SEC("license") = "GPL";