Add BPF verifier support for multi-level pointer parameters and return
values in BPF trampolines. The implementation treats these parameters as
SCALAR_VALUE.

Signed-off-by: Slava Imameev <[email protected]>
---
 kernel/bpf/btf.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 7708958e3fb8..ebb1b0c3f993 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -760,6 +760,21 @@ const struct btf_type *btf_type_resolve_func_ptr(const 
struct btf *btf,
        return NULL;
 }
 
+static bool is_multilevel_ptr(const struct btf *btf, const struct btf_type *t)
+{
+       u32 depth = 0;
+
+       if (!btf_type_is_ptr(t))
+               return false;
+
+       do {
+               depth += 1;
+               t = btf_type_skip_modifiers(btf, t->type, NULL);
+       } while (btf_type_is_ptr(t) && depth < 2);
+
+       return depth > 1;
+}
+
 /* Types that act only as a source, not sink or intermediate
  * type when resolving.
  */
@@ -6905,8 +6920,11 @@ bool btf_ctx_access(int off, int size, enum 
bpf_access_type type,
        /*
         * If it's a pointer to void, it's the same as scalar from the verifier
         * safety POV. Either way, no futher pointer walking is allowed.
+        * Multilevel pointers (e.g., int**, struct foo**, char***) of any type
+        * are treated as scalars because the verifier lacks the context to 
infer
+        * the size of their target memory regions.
         */
-       if (is_void_or_int_ptr(btf, t))
+       if (is_void_or_int_ptr(btf, t) || is_multilevel_ptr(btf, t))
                return true;
 
        /* this is a pointer to another type */
-- 
2.34.1


Reply via email to