bpf-next-for-netdev

-----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQQ6NaUOruQGUkvPdG4raS+Z+3y5EwUCaIJYlAAKCRAraS+Z+3y5
 E5MFAQDW29BJyjRbB75oy6RxmFZX+xFmGgmy1XO3w822gIwgzQD/WzhsmFPDYv/F
 7iOpLvez6zTySUdTJXJGCTvYJG5EHwU=
 =U8S4
 -----END PGP SIGNATURE-----

Merge tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next

Martin KaFai Lau says:

====================
pull-request: bpf-next 2025-07-24

We've added 3 non-merge commits during the last 3 day(s) which contain
a total of 4 files changed, 40 insertions(+), 15 deletions(-).

The main changes are:

1) Improved verifier error message for incorrect narrower load from
   pointer field in ctx, from Paul Chaignon.

2) Disabled migration in nf_hook_run_bpf to address a syzbot report,
   from Kuniyuki Iwashima.

* tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next:
  selftests/bpf: Test invalid narrower ctx load
  bpf: Reject narrower access to pointer ctx fields
  bpf: Disable migration in nf_hook_run_bpf().
====================

Link: https://patch.msgid.link/20250724173306.3578483-1-martin.lau@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2025-07-24 18:02:23 -07:00
commit a4f5759b6f
4 changed files with 40 additions and 15 deletions

View File

@ -2440,22 +2440,22 @@ static bool cg_sockopt_is_valid_access(int off, int size,
}
switch (off) {
case offsetof(struct bpf_sockopt, sk):
case bpf_ctx_range_ptr(struct bpf_sockopt, sk):
if (size != sizeof(__u64))
return false;
info->reg_type = PTR_TO_SOCKET;
break;
case offsetof(struct bpf_sockopt, optval):
case bpf_ctx_range_ptr(struct bpf_sockopt, optval):
if (size != sizeof(__u64))
return false;
info->reg_type = PTR_TO_PACKET;
break;
case offsetof(struct bpf_sockopt, optval_end):
case bpf_ctx_range_ptr(struct bpf_sockopt, optval_end):
if (size != sizeof(__u64))
return false;
info->reg_type = PTR_TO_PACKET_END;
break;
case offsetof(struct bpf_sockopt, retval):
case bpf_ctx_range(struct bpf_sockopt, retval):
if (size != size_default)
return false;
return prog->expected_attach_type == BPF_CGROUP_GETSOCKOPT;

View File

@ -8699,7 +8699,7 @@ static bool bpf_skb_is_valid_access(int off, int size, enum bpf_access_type type
if (size != sizeof(__u64))
return false;
break;
case offsetof(struct __sk_buff, sk):
case bpf_ctx_range_ptr(struct __sk_buff, sk):
if (type == BPF_WRITE || size != sizeof(__u64))
return false;
info->reg_type = PTR_TO_SOCK_COMMON_OR_NULL;
@ -9277,7 +9277,7 @@ static bool sock_addr_is_valid_access(int off, int size,
return false;
}
break;
case offsetof(struct bpf_sock_addr, sk):
case bpf_ctx_range_ptr(struct bpf_sock_addr, sk):
if (type != BPF_READ)
return false;
if (size != sizeof(__u64))
@ -9327,17 +9327,17 @@ static bool sock_ops_is_valid_access(int off, int size,
if (size != sizeof(__u64))
return false;
break;
case offsetof(struct bpf_sock_ops, sk):
case bpf_ctx_range_ptr(struct bpf_sock_ops, sk):
if (size != sizeof(__u64))
return false;
info->reg_type = PTR_TO_SOCKET_OR_NULL;
break;
case offsetof(struct bpf_sock_ops, skb_data):
case bpf_ctx_range_ptr(struct bpf_sock_ops, skb_data):
if (size != sizeof(__u64))
return false;
info->reg_type = PTR_TO_PACKET;
break;
case offsetof(struct bpf_sock_ops, skb_data_end):
case bpf_ctx_range_ptr(struct bpf_sock_ops, skb_data_end):
if (size != sizeof(__u64))
return false;
info->reg_type = PTR_TO_PACKET_END;
@ -9346,7 +9346,7 @@ static bool sock_ops_is_valid_access(int off, int size,
bpf_ctx_record_field_size(info, size_default);
return bpf_ctx_narrow_access_ok(off, size,
size_default);
case offsetof(struct bpf_sock_ops, skb_hwtstamp):
case bpf_ctx_range(struct bpf_sock_ops, skb_hwtstamp):
if (size != sizeof(__u64))
return false;
break;
@ -9416,17 +9416,17 @@ static bool sk_msg_is_valid_access(int off, int size,
return false;
switch (off) {
case offsetof(struct sk_msg_md, data):
case bpf_ctx_range_ptr(struct sk_msg_md, data):
info->reg_type = PTR_TO_PACKET;
if (size != sizeof(__u64))
return false;
break;
case offsetof(struct sk_msg_md, data_end):
case bpf_ctx_range_ptr(struct sk_msg_md, data_end):
info->reg_type = PTR_TO_PACKET_END;
if (size != sizeof(__u64))
return false;
break;
case offsetof(struct sk_msg_md, sk):
case bpf_ctx_range_ptr(struct sk_msg_md, sk):
if (size != sizeof(__u64))
return false;
info->reg_type = PTR_TO_SOCKET;
@ -11632,7 +11632,7 @@ static bool sk_lookup_is_valid_access(int off, int size,
return false;
switch (off) {
case offsetof(struct bpf_sk_lookup, sk):
case bpf_ctx_range_ptr(struct bpf_sk_lookup, sk):
info->reg_type = PTR_TO_SOCKET_OR_NULL;
return size == sizeof(__u64);

View File

@ -17,7 +17,7 @@ static unsigned int nf_hook_run_bpf(void *bpf_prog, struct sk_buff *skb,
.skb = skb,
};
return bpf_prog_run(prog, &ctx);
return bpf_prog_run_pin_on_cpu(prog, &ctx);
}
struct bpf_nf_link {

View File

@ -218,4 +218,29 @@ __naked void null_check_8_null_bind(void)
: __clobber_all);
}
#define narrow_load(type, ctx, field) \
SEC(type) \
__description("narrow load on field " #field " of " #ctx) \
__failure __msg("invalid bpf_context access") \
__naked void invalid_narrow_load##ctx##field(void) \
{ \
asm volatile (" \
r1 = *(u32 *)(r1 + %[off]); \
r0 = 0; \
exit;" \
: \
: __imm_const(off, offsetof(struct ctx, field) + 4) \
: __clobber_all); \
}
narrow_load("cgroup/getsockopt", bpf_sockopt, sk);
narrow_load("cgroup/getsockopt", bpf_sockopt, optval);
narrow_load("cgroup/getsockopt", bpf_sockopt, optval_end);
narrow_load("tc", __sk_buff, sk);
narrow_load("cgroup/bind4", bpf_sock_addr, sk);
narrow_load("sockops", bpf_sock_ops, sk);
narrow_load("sockops", bpf_sock_ops, skb_data);
narrow_load("sockops", bpf_sock_ops, skb_data_end);
narrow_load("sockops", bpf_sock_ops, skb_hwtstamp);
char _license[] SEC("license") = "GPL";