From: Martin KaFai Lau <martin.lau@linux.dev>
To: Amery Hung <amery.hung@bytedance.com>
Cc: bpf@vger.kernel.org, netdev@vger.kernel.org,
daniel@iogearbox.net, andrii@kernel.org,
alexei.starovoitov@gmail.com, martin.lau@kernel.org,
sinquersw@gmail.com, toke@redhat.com, jhs@mojatatu.com,
jiri@resnulli.us, stfomichev@gmail.com,
ekarani.silvestre@ccc.ufcg.edu.br, yangpeihao@sjtu.edu.cn,
xiyou.wangcong@gmail.com, yepeilin.cs@gmail.com,
ameryhung@gmail.com
Subject: Re: [PATCH bpf-next v1 03/13] bpf: Allow struct_ops prog to return referenced kptr
Date: Wed, 18 Dec 2024 14:29:41 -0800 [thread overview]
Message-ID: <6f857105-3f75-47ea-934c-129289b475e1@linux.dev> (raw)
In-Reply-To: <20241213232958.2388301-4-amery.hung@bytedance.com>
On 12/13/24 3:29 PM, Amery Hung wrote:
> @@ -15993,13 +16001,15 @@ static int check_return_code(struct bpf_verifier_env *env, int regno, const char
> const char *exit_ctx = "At program exit";
> struct tnum enforce_attach_type_range = tnum_unknown;
> const struct bpf_prog *prog = env->prog;
> - struct bpf_reg_state *reg;
> + struct bpf_reg_state *reg = reg_state(env, regno);
> struct bpf_retval_range range = retval_range(0, 1);
> enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
> int err;
> struct bpf_func_state *frame = env->cur_state->frame[0];
> const bool is_subprog = frame->subprogno;
> bool return_32bit = false;
> + struct btf *btf = bpf_prog_get_target_btf(prog);
> + const struct btf_type *ret_type = NULL;
>
> /* LSM and struct_ops func-ptr's return type could be "void" */
> if (!is_subprog || frame->in_exception_callback_fn) {
> @@ -16008,10 +16018,31 @@ static int check_return_code(struct bpf_verifier_env *env, int regno, const char
> if (prog->expected_attach_type == BPF_LSM_CGROUP)
> /* See below, can be 0 or 0-1 depending on hook. */
> break;
> - fallthrough;
> + if (!prog->aux->attach_func_proto->type)
> + return 0;
> + break;
> case BPF_PROG_TYPE_STRUCT_OPS:
> if (!prog->aux->attach_func_proto->type)
> return 0;
> +
> + if (frame->in_exception_callback_fn)
> + break;
> +
> + /* Allow a struct_ops program to return a referenced kptr if it
> + * matches the operator's return type and is in its unmodified
> + * form. A scalar zero (i.e., a null pointer) is also allowed.
> + */
> + ret_type = btf_type_by_id(btf, prog->aux->attach_func_proto->type);
> + if (btf_type_is_ptr(ret_type) && reg->type & PTR_TO_BTF_ID &&
The "reg->type & PTR_TO_BTF_ID" does not look right. It should be
"base_type(reg->type) == PTR_TO_BTF_ID".
> + reg->ref_obj_id) {
> + if (reg->btf_id != ret_type->type) {
reg->btf could be a bpf prog's btf (i.e. prog->aux->btf) instead of the kernel
btf, so only comparing btf_id here is not very correct.
One way could be to first compare the reg->btf == prog->aux->attach_btf.
prog->aux->attach_btf here must be a kernel btf.
Another way is, btf_type_resolve_ptr() should be a better helper than
btf_type_by_id() here. It only returns non NULL if the type is a pointer and
also skips the modifiers like "const" before returning. Then it can directly
compare the "struct btf_type *" returned by
'btf_type_resolve_ptr(prog->aux->attach_btf, prog->aux->attach_func_proto->type,
NULL)' and 'btf_type_resolve_ptr(reg->btf, reg->btf_id, NULL)'
May as well enforce the pointer returned by an "ops" must be a struct (i.e.
__btf_type_is_struct(t) == true). This enforcement can be done in
bpf_struct_ops_desc_init().
> + verbose(env, "Return kptr type, struct %s, doesn't match function prototype, struct %s\n",
> + btf_type_name(reg->btf, reg->btf_id),
> + btf_type_name(btf, ret_type->type));
> + return -EINVAL;
> + }
> + return __check_ptr_off_reg(env, reg, regno, false);
> + }
> break;
> default:
> break;
> @@ -16033,8 +16064,6 @@ static int check_return_code(struct bpf_verifier_env *env, int regno, const char
> return -EACCES;
> }
>
> - reg = cur_regs(env) + regno;
> -
> if (frame->in_async_callback_fn) {
> /* enforce return zero from async callbacks like timer */
> exit_ctx = "At async callback return";
> @@ -16133,6 +16162,11 @@ static int check_return_code(struct bpf_verifier_env *env, int regno, const char
> case BPF_PROG_TYPE_NETFILTER:
> range = retval_range(NF_DROP, NF_ACCEPT);
> break;
> + case BPF_PROG_TYPE_STRUCT_OPS:
> + if (!ret_type || !btf_type_is_ptr(ret_type))
> + return 0;
> + range = retval_range(0, 0);
> + break;
> case BPF_PROG_TYPE_EXT:
> /* freplace program can return anything as its return value
> * depends on the to-be-replaced kernel func or bpf program.
next prev parent reply other threads:[~2024-12-18 22:29 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-13 23:29 [PATCH bpf-next v1 00/13] bpf qdisc Amery Hung
2024-12-13 23:29 ` [PATCH bpf-next v1 01/13] bpf: Support getting referenced kptr from struct_ops argument Amery Hung
2024-12-18 0:58 ` Martin KaFai Lau
2024-12-18 1:24 ` Alexei Starovoitov
2024-12-18 16:09 ` Amery Hung
2024-12-18 17:20 ` Alexei Starovoitov
2024-12-18 1:44 ` Jakub Kicinski
2024-12-18 16:57 ` Amery Hung
2024-12-19 23:06 ` Martin KaFai Lau
2024-12-13 23:29 ` [PATCH bpf-next v1 02/13] selftests/bpf: Test referenced kptr arguments of struct_ops programs Amery Hung
2024-12-18 1:17 ` Martin KaFai Lau
2024-12-18 16:10 ` Amery Hung
2024-12-19 3:40 ` Yonghong Song
2024-12-19 20:49 ` Amery Hung
2024-12-13 23:29 ` [PATCH bpf-next v1 03/13] bpf: Allow struct_ops prog to return referenced kptr Amery Hung
2024-12-18 22:29 ` Martin KaFai Lau [this message]
2024-12-13 23:29 ` [PATCH bpf-next v1 04/13] selftests/bpf: Test returning referenced kptr from struct_ops programs Amery Hung
2024-12-13 23:29 ` [PATCH bpf-next v1 05/13] bpf: net_sched: Support implementation of Qdisc_ops in bpf Amery Hung
2024-12-14 4:51 ` Cong Wang
2024-12-18 23:37 ` Martin KaFai Lau
2024-12-13 23:29 ` [PATCH bpf-next v1 06/13] bpf: net_sched: Add basic bpf qdisc kfuncs Amery Hung
2024-12-18 17:11 ` Amery Hung
2024-12-19 7:37 ` Martin KaFai Lau
2024-12-20 0:32 ` Amery Hung
2024-12-13 23:29 ` [PATCH bpf-next v1 07/13] bpf: net_sched: Add a qdisc watchdog timer Amery Hung
2024-12-19 1:16 ` Martin KaFai Lau
2024-12-20 19:24 ` Amery Hung
2024-12-13 23:29 ` [PATCH bpf-next v1 08/13] bpf: net_sched: Support updating bstats Amery Hung
2024-12-13 23:29 ` [PATCH bpf-next v1 09/13] bpf: net_sched: Support updating qstats Amery Hung
2024-12-13 23:29 ` [PATCH bpf-next v1 10/13] bpf: net_sched: Allow writing to more Qdisc members Amery Hung
2024-12-13 23:29 ` [PATCH bpf-next v1 11/13] libbpf: Support creating and destroying qdisc Amery Hung
2024-12-17 18:32 ` Andrii Nakryiko
2024-12-17 19:08 ` Amery Hung
2024-12-13 23:29 ` [PATCH bpf-next v1 12/13] selftests: Add a basic fifo qdisc test Amery Hung
2024-12-13 23:29 ` [PATCH bpf-next v1 13/13] selftests: Add a bpf fq qdisc to selftest Amery Hung
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=6f857105-3f75-47ea-934c-129289b475e1@linux.dev \
--to=martin.lau@linux.dev \
--cc=alexei.starovoitov@gmail.com \
--cc=amery.hung@bytedance.com \
--cc=ameryhung@gmail.com \
--cc=andrii@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=ekarani.silvestre@ccc.ufcg.edu.br \
--cc=jhs@mojatatu.com \
--cc=jiri@resnulli.us \
--cc=martin.lau@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=sinquersw@gmail.com \
--cc=stfomichev@gmail.com \
--cc=toke@redhat.com \
--cc=xiyou.wangcong@gmail.com \
--cc=yangpeihao@sjtu.edu.cn \
--cc=yepeilin.cs@gmail.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).