From: Jiri Olsa <jolsa@kernel.org>
To: Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andriin@fb.com>
Cc: netdev@vger.kernel.org, bpf@vger.kernel.org,
Song Liu <songliubraving@fb.com>, Yonghong Song <yhs@fb.com>,
Martin KaFai Lau <kafai@fb.com>, David Miller <davem@redhat.com>,
John Fastabend <john.fastabend@gmail.com>,
Wenbo Zhang <ethercflow@gmail.com>,
KP Singh <kpsingh@chromium.org>,
Brendan Gregg <bgregg@netflix.com>,
Florent Revest <revest@chromium.org>,
Al Viro <viro@zeniv.linux.org.uk>
Subject: [PATCH v9 bpf-next 07/14] bpf: Factor btf_struct_access function
Date: Sat, 1 Aug 2020 19:03:15 +0200 [thread overview]
Message-ID: <20200801170322.75218-8-jolsa@kernel.org> (raw)
In-Reply-To: <20200801170322.75218-1-jolsa@kernel.org>
Adding btf_struct_walk function that walks through the
struct type + given offset and returns following values:
enum bpf_struct_walk_result {
/* < 0 error */
WALK_SCALAR = 0,
WALK_PTR,
WALK_STRUCT,
};
WALK_SCALAR - when SCALAR_VALUE is found
WALK_PTR - when pointer value is found, its ID is stored
in 'next_btf_id' output param
WALK_STRUCT - when nested struct object is found, its ID is stored
in 'next_btf_id' output param
It will be used in following patches to get all nested
struct objects for given type and offset.
The btf_struct_access now calls btf_struct_walk function,
as long as it gets nested structs as return value.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
kernel/bpf/btf.c | 75 +++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 65 insertions(+), 10 deletions(-)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 0f995038b589..7bacc2f56061 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -3886,16 +3886,22 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
return true;
}
-int btf_struct_access(struct bpf_verifier_log *log,
- const struct btf_type *t, int off, int size,
- enum bpf_access_type atype,
- u32 *next_btf_id)
+enum bpf_struct_walk_result {
+ /* < 0 error */
+ WALK_SCALAR = 0,
+ WALK_PTR,
+ WALK_STRUCT,
+};
+
+static int btf_struct_walk(struct bpf_verifier_log *log,
+ const struct btf_type *t, int off, int size,
+ u32 *next_btf_id)
{
u32 i, moff, mtrue_end, msize = 0, total_nelems = 0;
const struct btf_type *mtype, *elem_type = NULL;
const struct btf_member *member;
const char *tname, *mname;
- u32 vlen;
+ u32 vlen, elem_id, mid;
again:
tname = __btf_name_by_offset(btf_vmlinux, t->name_off);
@@ -3966,7 +3972,7 @@ int btf_struct_access(struct bpf_verifier_log *log,
*/
if (off <= moff &&
BITS_ROUNDUP_BYTES(end_bit) <= off + size)
- return SCALAR_VALUE;
+ return WALK_SCALAR;
/* off may be accessing a following member
*
@@ -3988,11 +3994,13 @@ int btf_struct_access(struct bpf_verifier_log *log,
break;
/* type of the field */
+ mid = member->type;
mtype = btf_type_by_id(btf_vmlinux, member->type);
mname = __btf_name_by_offset(btf_vmlinux, member->name_off);
mtype = __btf_resolve_size(btf_vmlinux, mtype, &msize,
- &elem_type, NULL, &total_nelems, NULL);
+ &elem_type, &elem_id, &total_nelems,
+ &mid);
if (IS_ERR(mtype)) {
bpf_log(log, "field %s doesn't have size\n", mname);
return -EFAULT;
@@ -4054,6 +4062,7 @@ int btf_struct_access(struct bpf_verifier_log *log,
elem_idx = (off - moff) / msize;
moff += elem_idx * msize;
mtype = elem_type;
+ mid = elem_id;
}
/* the 'off' we're looking for is either equal to start
@@ -4063,6 +4072,12 @@ int btf_struct_access(struct bpf_verifier_log *log,
/* our field must be inside that union or struct */
t = mtype;
+ /* return if the offset matches the member offset */
+ if (off == moff) {
+ *next_btf_id = mid;
+ return WALK_STRUCT;
+ }
+
/* adjust offset we're looking for */
off -= moff;
goto again;
@@ -4078,11 +4093,10 @@ int btf_struct_access(struct bpf_verifier_log *log,
mname, moff, tname, off, size);
return -EACCES;
}
-
stype = btf_type_skip_modifiers(btf_vmlinux, mtype->type, &id);
if (btf_type_is_struct(stype)) {
*next_btf_id = id;
- return PTR_TO_BTF_ID;
+ return WALK_PTR;
}
}
@@ -4099,12 +4113,53 @@ int btf_struct_access(struct bpf_verifier_log *log,
return -EACCES;
}
- return SCALAR_VALUE;
+ return WALK_SCALAR;
}
bpf_log(log, "struct %s doesn't have field at offset %d\n", tname, off);
return -EINVAL;
}
+int btf_struct_access(struct bpf_verifier_log *log,
+ const struct btf_type *t, int off, int size,
+ enum bpf_access_type atype __maybe_unused,
+ u32 *next_btf_id)
+{
+ int err;
+ u32 id;
+
+ do {
+ err = btf_struct_walk(log, t, off, size, &id);
+
+ switch (err) {
+ case WALK_PTR:
+ /* If we found the pointer or scalar on t+off,
+ * we're done.
+ */
+ *next_btf_id = id;
+ return PTR_TO_BTF_ID;
+ case WALK_SCALAR:
+ return SCALAR_VALUE;
+ case WALK_STRUCT:
+ /* We found nested struct, so continue the search
+ * by diving in it. At this point the offset is
+ * aligned with the new type, so set it to 0.
+ */
+ t = btf_type_by_id(btf_vmlinux, id);
+ off = 0;
+ break;
+ default:
+ /* It's either error or unknown return value..
+ * scream and leave.
+ */
+ if (WARN_ONCE(err > 0, "unknown btf_struct_walk return value"))
+ return -EINVAL;
+ return err;
+ }
+ } while (t);
+
+ return -EINVAL;
+}
+
int btf_resolve_helper_id(struct bpf_verifier_log *log,
const struct bpf_func_proto *fn, int arg)
{
--
2.25.4
next prev parent reply other threads:[~2020-08-01 17:04 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-01 17:03 [PATCH v9 bpf-next 00/14] bpf: Add d_path helper Jiri Olsa
2020-08-01 17:03 ` [PATCH v9 bpf-next 01/14] tools resolve_btfids: Add size check to get_id function Jiri Olsa
2020-08-05 6:00 ` Andrii Nakryiko
2020-08-01 17:03 ` [PATCH v9 bpf-next 02/14] tools resolve_btfids: Add support for set symbols Jiri Olsa
2020-08-05 6:04 ` Andrii Nakryiko
2020-08-01 17:03 ` [PATCH v9 bpf-next 03/14] bpf: Move btf_resolve_size into __btf_resolve_size Jiri Olsa
2020-08-01 17:03 ` [PATCH v9 bpf-next 04/14] bpf: Add elem_id pointer as argument to __btf_resolve_size Jiri Olsa
2020-08-01 17:03 ` [PATCH v9 bpf-next 05/14] bpf: Add type_id " Jiri Olsa
2020-08-05 6:05 ` Andrii Nakryiko
2020-08-01 17:03 ` [PATCH v9 bpf-next 06/14] bpf: Remove recursion call in btf_struct_access Jiri Olsa
2020-08-05 6:12 ` Andrii Nakryiko
2020-08-05 17:36 ` Jiri Olsa
2020-08-01 17:03 ` Jiri Olsa [this message]
2020-08-05 6:18 ` [PATCH v9 bpf-next 07/14] bpf: Factor btf_struct_access function Andrii Nakryiko
2020-08-01 17:03 ` [PATCH v9 bpf-next 08/14] bpf: Add btf_struct_ids_match function Jiri Olsa
2020-08-05 6:27 ` Andrii Nakryiko
2020-08-05 17:56 ` Jiri Olsa
2020-08-05 21:31 ` Jiri Olsa
2020-08-05 21:57 ` Andrii Nakryiko
2020-08-01 17:03 ` [PATCH v9 bpf-next 09/14] bpf: Add BTF_SET_START/END macros Jiri Olsa
2020-08-05 6:29 ` Andrii Nakryiko
2020-08-01 17:03 ` [PATCH v9 bpf-next 10/14] bpf: Add d_path helper Jiri Olsa
2020-08-02 3:13 ` Alexei Starovoitov
2020-08-02 18:26 ` Jiri Olsa
2020-08-05 6:35 ` Andrii Nakryiko
2020-08-05 17:58 ` Jiri Olsa
2020-08-05 21:01 ` Jiri Olsa
2020-08-05 21:09 ` Andrii Nakryiko
2020-08-07 0:31 ` KP Singh
2020-08-07 8:35 ` Jiri Olsa
2020-08-07 9:42 ` KP Singh
2020-08-01 17:03 ` [PATCH v9 bpf-next 11/14] bpf: Update .BTF_ids section in btf.rst with sets info Jiri Olsa
2020-08-01 17:03 ` [PATCH v9 bpf-next 12/14] selftests/bpf: Add verifier test for d_path helper Jiri Olsa
2020-08-01 17:03 ` [PATCH v9 bpf-next 13/14] selftests/bpf: Add " Jiri Olsa
2020-08-05 6:40 ` Andrii Nakryiko
2020-08-05 18:00 ` Jiri Olsa
2020-08-01 17:03 ` [PATCH v9 bpf-next 14/14] selftests/bpf: Add set test to resolve_btfids Jiri Olsa
2020-08-05 6:41 ` Andrii Nakryiko
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=20200801170322.75218-8-jolsa@kernel.org \
--to=jolsa@kernel.org \
--cc=andriin@fb.com \
--cc=ast@kernel.org \
--cc=bgregg@netflix.com \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@redhat.com \
--cc=ethercflow@gmail.com \
--cc=john.fastabend@gmail.com \
--cc=kafai@fb.com \
--cc=kpsingh@chromium.org \
--cc=netdev@vger.kernel.org \
--cc=revest@chromium.org \
--cc=songliubraving@fb.com \
--cc=viro@zeniv.linux.org.uk \
--cc=yhs@fb.com \
/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;
as well as URLs for NNTP newsgroup(s).