From: thinker.li@gmail.com
To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev,
song@kernel.org, kernel-team@meta.com, andrii@kernel.org,
davemarchevsky@meta.com, dvernet@meta.com
Cc: sinquersw@gmail.com, kuifeng@meta.com,
Kui-Feng Lee <thinker.li@gmail.com>
Subject: [RFC bpf-next v4 2/6] bpf: Extend PTR_TO_BTF_ID to handle pointers to scalar and array types.
Date: Fri, 2 Feb 2024 14:05:12 -0800 [thread overview]
Message-ID: <20240202220516.1165466-3-thinker.li@gmail.com> (raw)
In-Reply-To: <20240202220516.1165466-1-thinker.li@gmail.com>
From: Kui-Feng Lee <thinker.li@gmail.com>
The verifier calls btf_struct_access() to check the access for
PTR_TO_BTF_ID. btf_struct_access() supported only pointer to struct types
(including union). We add the support of scalar types and array types.
btf_reloc_array_access() is responsible for relocating the access from the
whole array to an element in the array. That means to adjust the offset
relatively to the start of an element and change the type to the type of
the element. With this relocation, we can check the access against the
element type instead of the array type itself.
After relocation, the struct types, including union types, will continue
the loop of btf_struct_walk(). Other types are treated as scalar types,
including pointers, and return from btf_struct_access().
Signed-off-by: Kui-Feng Lee <thinker.li@gmail.com>
---
kernel/bpf/btf.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 0847035bba99..d3f94d04c69d 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -6590,6 +6590,61 @@ static int btf_struct_walk(struct bpf_verifier_log *log, const struct btf *btf,
return -EINVAL;
}
+/* Relocate the access relatively to the beginning of an element in an
+ * array.
+ *
+ * The offset is adjusted relatively to the beginning of the element and the
+ * type is adjusted to the type of the element.
+ *
+ * Return NULL for scalar, enum, and pointer type.
+ * Return a btf_type pointer for struct and union.
+ */
+static const struct btf_type *
+btf_reloc_array_access(struct bpf_verifier_log *log, const struct btf *btf,
+ const struct btf_type *t, int *off, int size)
+{
+ const struct btf_type *rt, *elem_type;
+ u32 rt_size, elem_id, total_nelems, rt_id, elem_size;
+ u32 elem_idx;
+
+ rt = __btf_resolve_size(btf, t, &rt_size, &elem_type, &elem_id,
+ &total_nelems, &rt_id);
+ if (IS_ERR(rt))
+ return rt;
+ if (btf_type_is_array(rt)) {
+ if (*off >= rt_size) {
+ bpf_log(log, "access out of range of type %s with offset %d and size %u\n",
+ __btf_name_by_offset(btf, t->name_off), *off, rt_size);
+ return ERR_PTR(-EACCES);
+ }
+
+ /* Multi-dimensional arrays are flattened by
+ * __btf_resolve_size(). Check the comment in
+ * btf_struct_walk().
+ */
+ elem_size = rt_size / total_nelems;
+ elem_idx = *off / elem_size;
+ /* Relocate the offset relatively to the start of the
+ * element at elem_idx.
+ */
+ *off -= elem_idx * elem_size;
+ rt = elem_type;
+ rt_size = elem_size;
+ }
+
+ if (btf_type_is_struct(rt))
+ return rt;
+
+ if (*off + size > rt_size) {
+ bpf_log(log, "access beyond the range of type %s with offset %d and size %d\n",
+ __btf_name_by_offset(btf, rt->name_off), *off, size);
+ return ERR_PTR(-EACCES);
+ }
+
+ /* The access is accepted as a scalar. */
+ return NULL;
+}
+
int btf_struct_access(struct bpf_verifier_log *log,
const struct bpf_reg_state *reg,
int off, int size, enum bpf_access_type atype __maybe_unused,
@@ -6625,6 +6680,12 @@ int btf_struct_access(struct bpf_verifier_log *log,
}
t = btf_type_by_id(btf, id);
+ t = btf_reloc_array_access(log, btf, t, &off, size);
+ if (IS_ERR(t))
+ return PTR_ERR(t);
+ if (!t)
+ return SCALAR_VALUE;
+
do {
err = btf_struct_walk(log, btf, t, off, size, &id, &tmp_flag, field_name);
--
2.34.1
next prev parent reply other threads:[~2024-02-02 22:05 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-02 22:05 [RFC bpf-next v4 0/6] Support PTR_MAYBE_NULL for struct_ops arguments thinker.li
2024-02-02 22:05 ` [RFC bpf-next v4 1/6] bpf: Allow PTR_TO_BTF_ID even for pointers to int thinker.li
2024-02-02 22:05 ` thinker.li [this message]
2024-02-03 0:52 ` [RFC bpf-next v4 2/6] bpf: Extend PTR_TO_BTF_ID to handle pointers to scalar and array types Martin KaFai Lau
2024-02-03 1:03 ` Kui-Feng Lee
2024-02-02 22:05 ` [RFC bpf-next v4 3/6] bpf: Remove an unnecessary check thinker.li
2024-02-03 0:46 ` Martin KaFai Lau
2024-02-03 1:03 ` Kui-Feng Lee
2024-02-02 22:05 ` [RFC bpf-next v4 4/6] bpf: add btf pointer to struct bpf_ctx_arg_aux thinker.li
2024-02-02 22:05 ` [RFC bpf-next v4 5/6] bpf: Create argument information for nullable arguments thinker.li
2024-02-03 0:40 ` Martin KaFai Lau
2024-02-03 1:57 ` Kui-Feng Lee
2024-02-04 0:21 ` Kui-Feng Lee
2024-02-05 1:53 ` Kui-Feng Lee
2024-02-02 22:05 ` [RFC bpf-next v4 6/6] selftests/bpf: Test PTR_MAYBE_NULL arguments of struct_ops operators thinker.li
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240202220516.1165466-3-thinker.li@gmail.com \
--to=thinker.li@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=davemarchevsky@meta.com \
--cc=dvernet@meta.com \
--cc=kernel-team@meta.com \
--cc=kuifeng@meta.com \
--cc=martin.lau@linux.dev \
--cc=sinquersw@gmail.com \
--cc=song@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox