All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yonghong Song <yhs@fb.com>
To: <bpf@vger.kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>, <kernel-team@fb.com>
Subject: [RFC PATCH bpf-next 6/7] bpf: Populate struct value info in btf_func_model
Date: Tue, 26 Jul 2022 10:12:02 -0700	[thread overview]
Message-ID: <20220726171202.714640-1-yhs@fb.com> (raw)
In-Reply-To: <20220726171129.708371-1-yhs@fb.com>

Add struct value support in btf_ctx_access() and btf_distill_func_proto().
Reject if a struct argument size is greater than 16 as struct size greater than
16 likely passed in memory ([1], see function X86_64ABIInfo::postMerge()).

 [1] https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/TargetInfo.cpp

Signed-off-by: Yonghong Song <yhs@fb.com>
---
 kernel/bpf/btf.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 40 insertions(+), 5 deletions(-)

diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 3bbcc985a651..c4c19c89611b 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -5339,7 +5339,7 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
 	struct bpf_verifier_log *log = info->log;
 	const struct btf_param *args;
 	const char *tag_value;
-	u32 nr_args, arg;
+	u32 nr_args, arg, curr_tid = 0;
 	int i, ret;
 
 	if (off % 8) {
@@ -5385,6 +5385,7 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
 			 */
 			if (!t)
 				return true;
+			curr_tid = t->type;
 			t = btf_type_by_id(btf, t->type);
 			break;
 		case BPF_MODIFY_RETURN:
@@ -5394,7 +5395,7 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
 			if (!t)
 				return false;
 
-			t = btf_type_skip_modifiers(btf, t->type, NULL);
+			t = btf_type_skip_modifiers(btf, t->type, &curr_tid);
 			if (!btf_type_is_small_int(t)) {
 				bpf_log(log,
 					"ret type %s not allowed for fmod_ret\n",
@@ -5411,15 +5412,25 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
 		if (!t)
 			/* Default prog with MAX_BPF_FUNC_REG_ARGS args */
 			return true;
+		curr_tid = args[arg].type;
 		t = btf_type_by_id(btf, args[arg].type);
 	}
 
 	/* skip modifiers */
-	while (btf_type_is_modifier(t))
+	while (btf_type_is_modifier(t)) {
+		curr_tid = t->type;
 		t = btf_type_by_id(btf, t->type);
+	}
 	if (btf_type_is_small_int(t) || btf_is_any_enum(t))
 		/* accessing a scalar */
 		return true;
+	if (__btf_type_is_struct(t) && curr_tid) {
+		info->reg_type = PTR_TO_BTF_ID;
+		info->btf = btf;
+		info->btf_id = curr_tid;
+		return true;
+	}
+
 	if (!btf_type_is_ptr(t)) {
 		bpf_log(log,
 			"func '%s' arg%d '%s' has type %s. Only pointer access is allowed\n",
@@ -5878,7 +5889,7 @@ static int __get_type_size(struct btf *btf, u32 btf_id,
 	if (!t)
 		return -EINVAL;
 	*ret_type = t;
-	if (btf_type_is_ptr(t))
+	if (btf_type_is_ptr(t) || __btf_type_is_struct(t))
 		/* kernel size of pointer. Not BPF's size of pointer*/
 		return sizeof(void *);
 	if (btf_type_is_int(t) || btf_is_any_enum(t))
@@ -5894,9 +5905,14 @@ int btf_distill_func_proto(struct bpf_verifier_log *log,
 {
 	const struct btf_param *args;
 	const struct btf_type *t;
-	u32 i, nargs;
+	u32 i, j = 0, nargs;
 	int ret;
 
+	for (i = 0; i < MAX_BPF_FUNC_STRUCT_ARGS; i++) {
+		m->struct_arg_idx[i] = 0;
+		m->struct_arg_bsize[i] = 0;
+	}
+
 	if (!func) {
 		/* BTF function prototype doesn't match the verifier types.
 		 * Fall back to MAX_BPF_FUNC_REG_ARGS u64 args.
@@ -5944,6 +5960,25 @@ int btf_distill_func_proto(struct bpf_verifier_log *log,
 				tname);
 			return -EINVAL;
 		}
+		if (__btf_type_is_struct(t)) {
+			if (t->size > 16) {
+				bpf_log(log,
+					"The function %s arg%d struct size exceeds 16 bytes.\n",
+					tname, i);
+				return -EINVAL;
+			}
+
+			if (j == MAX_BPF_FUNC_STRUCT_ARGS) {
+				bpf_log(log,
+					"The function %s has more than %d struct/union args.\n",
+					tname, MAX_BPF_FUNC_STRUCT_ARGS);
+				return -EINVAL;
+			}
+
+			m->struct_arg_idx[j] = i;
+			m->struct_arg_bsize[j] = t->size;
+			j++;
+		}
 		m->arg_size[i] = ret;
 	}
 	m->nr_args = nargs;
-- 
2.30.2


  parent reply	other threads:[~2022-07-26 17:12 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-26 17:11 [RFC PATCH bpf-next 0/7] bpf: Support struct value argument for trampoline base progs Yonghong Song
2022-07-26 17:11 ` [RFC PATCH bpf-next 1/7] bpf: Always return corresponding btf_type in __get_type_size() Yonghong Song
2022-07-26 17:11 ` [RFC PATCH bpf-next 2/7] bpf: Add struct argument info in btf_func_model Yonghong Song
2022-08-09  0:02   ` Andrii Nakryiko
2022-08-09 17:38     ` Yonghong Song
2022-08-10  0:25       ` Andrii Nakryiko
2022-08-11  6:24         ` Yonghong Song
2022-07-26 17:11 ` [RFC PATCH bpf-next 3/7] bpf: x86: Rename stack_size to regs_off in {save,restore}_regs() Yonghong Song
2022-07-26 17:11 ` [RFC PATCH bpf-next 4/7] bpf: x86: Support in-register struct arguments Yonghong Song
2022-07-29 11:10   ` Jiri Olsa
2022-07-31 17:00     ` Yonghong Song
2022-07-26 17:11 ` [RFC PATCH bpf-next 5/7] bpf: arm64: No support of struct value argument Yonghong Song
2022-07-26 17:12 ` Yonghong Song [this message]
2022-07-26 17:12 ` [RFC PATCH bpf-next 7/7] selftests/bpf: Add struct value tests with fentry programs Yonghong Song
2022-07-28 15:46 ` [RFC PATCH bpf-next 0/7] bpf: Support struct value argument for trampoline base progs Kui-Feng Lee
2022-07-28 17:46   ` Yonghong Song
2022-07-28 19:57     ` Kui-Feng Lee
2022-07-28 23:30       ` Yonghong Song
2022-07-29 18:04         ` Kui-Feng Lee
2022-08-02 23:46           ` Yonghong Song

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=20220726171202.714640-1-yhs@fb.com \
    --to=yhs@fb.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=kernel-team@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.