]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bpf: Check KF_bpf_rbtree_add_impl for the "case KF_ARG_PTR_TO_RB_NODE"
authorMartin KaFai Lau <martin.lau@kernel.org>
Tue, 6 May 2025 01:58:48 +0000 (18:58 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 6 May 2025 17:21:05 +0000 (10:21 -0700)
In a later patch, two new kfuncs will take the bpf_rb_node pointer arg.

struct bpf_rb_node *bpf_rbtree_left(struct bpf_rb_root *root,
    struct bpf_rb_node *node);
struct bpf_rb_node *bpf_rbtree_right(struct bpf_rb_root *root,
     struct bpf_rb_node *node);

In the check_kfunc_call, there is a "case KF_ARG_PTR_TO_RB_NODE"
to check if the reg->type should be an allocated pointer or should be
a non_owning_ref.

The later patch will need to ensure that the bpf_rb_node pointer passing
to the new bpf_rbtree_{left,right} must be a non_owning_ref. This
should be the same requirement as the existing bpf_rbtree_remove.

This patch swaps the current "if else" statement. Instead of checking
the bpf_rbtree_remove, it checks the bpf_rbtree_add. Then the new
bpf_rbtree_{left,right} will fall into the "else" case to make
the later patch simpler. bpf_rbtree_add should be the only
one that needs an allocated pointer.

This should be a no-op change considering there are only two kfunc(s)
taking bpf_rb_node pointer arg, rbtree_add and rbtree_remove.

Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Link: https://lore.kernel.org/r/20250506015857.817950-2-martin.lau@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/verifier.c

index 54c6953a8b84c2cd9f9394d83716e594bb96274e..2e1ce7debc166b063c73b2287477195d948a7c36 100644 (file)
@@ -13200,22 +13200,22 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
                                return ret;
                        break;
                case KF_ARG_PTR_TO_RB_NODE:
-                       if (meta->func_id == special_kfunc_list[KF_bpf_rbtree_remove]) {
-                               if (!type_is_non_owning_ref(reg->type) || reg->ref_obj_id) {
-                                       verbose(env, "rbtree_remove node input must be non-owning ref\n");
+                       if (meta->func_id == special_kfunc_list[KF_bpf_rbtree_add_impl]) {
+                               if (reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
+                                       verbose(env, "arg#%d expected pointer to allocated object\n", i);
                                        return -EINVAL;
                                }
-                               if (in_rbtree_lock_required_cb(env)) {
-                                       verbose(env, "rbtree_remove not allowed in rbtree cb\n");
+                               if (!reg->ref_obj_id) {
+                                       verbose(env, "allocated object must be referenced\n");
                                        return -EINVAL;
                                }
                        } else {
-                               if (reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
-                                       verbose(env, "arg#%d expected pointer to allocated object\n", i);
+                               if (!type_is_non_owning_ref(reg->type) || reg->ref_obj_id) {
+                                       verbose(env, "rbtree_remove node input must be non-owning ref\n");
                                        return -EINVAL;
                                }
-                               if (!reg->ref_obj_id) {
-                                       verbose(env, "allocated object must be referenced\n");
+                               if (in_rbtree_lock_required_cb(env)) {
+                                       verbose(env, "rbtree_remove not allowed in rbtree cb\n");
                                        return -EINVAL;
                                }
                        }