bpf: Invoke btf_struct_access() callback only for writes.
authorAlexei Starovoitov <ast@kernel.org>
Tue, 4 Apr 2023 04:50:22 +0000 (21:50 -0700)
committerAndrii Nakryiko <andrii@kernel.org>
Tue, 4 Apr 2023 23:57:03 +0000 (16:57 -0700)
Remove duplicated if (atype == BPF_READ) btf_struct_access() from
btf_struct_access() callback and invoke it only for writes. This is
possible to do because currently btf_struct_access() custom callback
always delegates to generic btf_struct_access() helper for BPF_READ
accesses.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: David Vernet <void@manifault.com>
Link: https://lore.kernel.org/bpf/20230404045029.82870-2-alexei.starovoitov@gmail.com
kernel/bpf/verifier.c
net/bpf/bpf_dummy_struct_ops.c
net/core/filter.c
net/ipv4/bpf_tcp_ca.c

index eaf9c5291cf0557668d2e5276e05289636ceb1af..83984568ccb48e734d87d32ce5d9d8461b466a2b 100644 (file)
@@ -5504,7 +5504,7 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env,
                return -EACCES;
        }
 
-       if (env->ops->btf_struct_access && !type_is_alloc(reg->type)) {
+       if (env->ops->btf_struct_access && !type_is_alloc(reg->type) && atype == BPF_WRITE) {
                if (!btf_is_kernel(reg->btf)) {
                        verbose(env, "verifier internal error: reg->btf must be kernel btf\n");
                        return -EFAULT;
index ff4f89a2b02a06eab671b0d8d2774bd79ef25076..9535c8506cdae03ea99614167c0447e8438e5fc7 100644 (file)
@@ -198,7 +198,7 @@ static int bpf_dummy_ops_btf_struct_access(struct bpf_verifier_log *log,
        if (err < 0)
                return err;
 
-       return atype == BPF_READ ? err : NOT_INIT;
+       return NOT_INIT;
 }
 
 static const struct bpf_verifier_ops bpf_dummy_verifier_ops = {
index 3370efad1ddabf0895a8f64a57434bf9bab30ce2..8b9f409a2ec35e4a73bab4b32df085c67c8047f1 100644 (file)
@@ -8753,9 +8753,6 @@ static int tc_cls_act_btf_struct_access(struct bpf_verifier_log *log,
 {
        int ret = -EACCES;
 
-       if (atype == BPF_READ)
-               return btf_struct_access(log, reg, off, size, atype, next_btf_id, flag);
-
        mutex_lock(&nf_conn_btf_access_lock);
        if (nfct_btf_struct_access)
                ret = nfct_btf_struct_access(log, reg, off, size, atype, next_btf_id, flag);
@@ -8830,9 +8827,6 @@ static int xdp_btf_struct_access(struct bpf_verifier_log *log,
 {
        int ret = -EACCES;
 
-       if (atype == BPF_READ)
-               return btf_struct_access(log, reg, off, size, atype, next_btf_id, flag);
-
        mutex_lock(&nf_conn_btf_access_lock);
        if (nfct_btf_struct_access)
                ret = nfct_btf_struct_access(log, reg, off, size, atype, next_btf_id, flag);
index ea21c96c03aa132a9fc344995df03f64f69b9163..d6465876bbf614d7c25a4fdb00996d1bf25a5d42 100644 (file)
@@ -78,9 +78,6 @@ static int bpf_tcp_ca_btf_struct_access(struct bpf_verifier_log *log,
        const struct btf_type *t;
        size_t end;
 
-       if (atype == BPF_READ)
-               return btf_struct_access(log, reg, off, size, atype, next_btf_id, flag);
-
        t = btf_type_by_id(reg->btf, reg->btf_id);
        if (t != tcp_sock_type) {
                bpf_log(log, "only read is supported\n");