bpf_tcp_ca_btf_struct_access() authorizes writes based on the BTF type
and member offset, but does not check pointer modifiers. A BPF program
can use bpf_rdonly_cast() to create an untrusted tcp_sock pointer and
write through an allowlisted member, bypassing the read-only cast.
Reject pointers with unsafe modifiers before checking the type and
member offset. Trusted struct_ops context pointers retain the existing
write access to the permitted TCP fields.
Fixes: a35b9af4ec2c ("bpf: Add a kfunc for generic type cast")
Cc: stable@vger.kernel.org
Reported-by: Vega <redacted>
Assisted-by: LLM
Signed-off-by: Zhiling Zou <redacted>
---
net/ipv4/bpf_tcp_ca.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/ipv4/bpf_tcp_ca.c b/net/ipv4/bpf_tcp_ca.c
index 791e15063237..252cbfe11e69 100644
--- a/net/ipv4/bpf_tcp_ca.c
+++ b/net/ipv4/bpf_tcp_ca.c
@@ -65,6 +65,11 @@ static int bpf_tcp_ca_btf_struct_access(struct bpf_verifier_log *log,
const struct btf_type *t;
size_t end;
+ if (bpf_type_has_unsafe_modifiers(reg->type)) {
+ bpf_log(log, "write through an unsafe tcp_sock pointer\n");
+ return -EACCES;
+ }
+
t = btf_type_by_id(reg->btf, reg->btf_id);
if (t != tcp_sock_type) {
bpf_log(log, "only read is supported\n");--
2.55.0