All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eduard Zingerman <eddyz87@gmail.com>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>, bpf@vger.kernel.org
Cc: daniel@iogearbox.net, andrii@kernel.org, memxor@gmail.com,
	tj@kernel.org,  brho@google.com, hannes@cmpxchg.org,
	lstoakes@gmail.com, akpm@linux-foundation.org,  urezki@gmail.com,
	hch@infradead.org, linux-mm@kvack.org, kernel-team@fb.com
Subject: Re: [PATCH v2 bpf-next 09/20] bpf: Recognize cast_kern/user instructions in the verifier.
Date: Sat, 10 Feb 2024 03:13:20 +0200	[thread overview]
Message-ID: <ed656ef900c33cb1bf9ffb06d0f4f59d7708e29c.camel@gmail.com> (raw)
In-Reply-To: <20240209040608.98927-10-alexei.starovoitov@gmail.com>

On Thu, 2024-02-08 at 20:05 -0800, Alexei Starovoitov wrote:
[...]

> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 3c77a3ab1192..5eeb9bf7e324 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c

[...]

> @@ -13837,6 +13844,21 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env,
>  
>  	dst_reg = &regs[insn->dst_reg];
>  	src_reg = NULL;
> +
> +	if (dst_reg->type == PTR_TO_ARENA) {
> +		struct bpf_insn_aux_data *aux = cur_aux(env);
> +
> +		if (BPF_CLASS(insn->code) == BPF_ALU64)
> +			/*
> +			 * 32-bit operations zero upper bits automatically.
> +			 * 64-bit operations need to be converted to 32.
> +			 */
> +			aux->needs_zext = true;

It should be possible to write an example, when the same insn is
visited with both PTR_TO_ARENA and some other PTR type.
Such examples should be rejected as is currently done in do_check()
for BPF_{ST,STX} using save_aux_ptr_type().

[...]

> @@ -13954,16 +13976,17 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
>  	} else if (opcode == BPF_MOV) {
>  
>  		if (BPF_SRC(insn->code) == BPF_X) {
> -			if (insn->imm != 0) {
> -				verbose(env, "BPF_MOV uses reserved fields\n");
> -				return -EINVAL;
> -			}
> -
>  			if (BPF_CLASS(insn->code) == BPF_ALU) {
> -				if (insn->off != 0 && insn->off != 8 && insn->off != 16) {
> +				if ((insn->off != 0 && insn->off != 8 && insn->off != 16) ||
> +				    insn->imm) {
>  					verbose(env, "BPF_MOV uses reserved fields\n");
>  					return -EINVAL;
>  				}
> +			} else if (insn->off == BPF_ARENA_CAST_KERN || insn->off == BPF_ARENA_CAST_USER) {
> +				if (!insn->imm) {
> +					verbose(env, "cast_kern/user insn must have non zero imm32\n");
> +					return -EINVAL;
> +				}
>  			} else {
>  				if (insn->off != 0 && insn->off != 8 && insn->off != 16 &&
>  				    insn->off != 32) {

I think it is now necessary to check insn->imm here,
as is it allows ALU64 move with non-zero imm.

> @@ -13993,7 +14016,12 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
>  			struct bpf_reg_state *dst_reg = regs + insn->dst_reg;
>  
>  			if (BPF_CLASS(insn->code) == BPF_ALU64) {
> -				if (insn->off == 0) {
> +				if (insn->imm) {
> +					/* off == BPF_ARENA_CAST_KERN || off == BPF_ARENA_CAST_USER */
> +					mark_reg_unknown(env, regs, insn->dst_reg);
> +					if (insn->off == BPF_ARENA_CAST_KERN)
> +						dst_reg->type = PTR_TO_ARENA;

This effectively allows casting anything to PTR_TO_ARENA.
Do we want to check that src_reg somehow originates from arena?
Might be tricky, a new type modifier bit or something like that.

> +				} else if (insn->off == 0) {
>  					/* case: R1 = R2
>  					 * copy register state to dest reg
>  					 */
> @@ -14059,6 +14087,9 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
>  						dst_reg->subreg_def = env->insn_idx + 1;
>  						coerce_subreg_to_size_sx(dst_reg, insn->off >> 3);
>  					}
> +				} else if (src_reg->type == PTR_TO_ARENA) {
> +					mark_reg_unknown(env, regs, insn->dst_reg);
> +					dst_reg->type = PTR_TO_ARENA;

This describes a case wX = wY, where rY is PTR_TO_ARENA,
should rX be marked as SCALAR instead of PTR_TO_ARENA?

[...]

> @@ -18235,6 +18272,31 @@ static int resolve_pseudo_ldimm64(struct bpf_verifier_env *env)
>  				fdput(f);
>  				return -EBUSY;
>  			}
> +			if (map->map_type == BPF_MAP_TYPE_ARENA) {
> +				if (env->prog->aux->arena) {

Does this have to be (env->prog->aux->arena && env->prog->aux->arena != map) ?

> +					verbose(env, "Only one arena per program\n");
> +					fdput(f);
> +					return -EBUSY;
> +				}

[...]

> @@ -18799,6 +18861,18 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
>  			   insn->code == (BPF_ST | BPF_MEM | BPF_W) ||
>  			   insn->code == (BPF_ST | BPF_MEM | BPF_DW)) {
>  			type = BPF_WRITE;
> +		} else if (insn->code == (BPF_ALU64 | BPF_MOV | BPF_X) && insn->imm) {
> +			if (insn->off == BPF_ARENA_CAST_KERN ||
> +			    (((struct bpf_map *)env->prog->aux->arena)->map_flags & BPF_F_NO_USER_CONV)) {
> +				/* convert to 32-bit mov that clears upper 32-bit */
> +				insn->code = BPF_ALU | BPF_MOV | BPF_X;
> +				/* clear off, so it's a normal 'wX = wY' from JIT pov */
> +				insn->off = 0;
> +			} /* else insn->off == BPF_ARENA_CAST_USER should be handled by JIT */
> +			continue;
> +		} else if (env->insn_aux_data[i + delta].needs_zext) {
> +			/* Convert BPF_CLASS(insn->code) == BPF_ALU64 to 32-bit ALU */
> +			insn->code = BPF_ALU | BPF_OP(insn->code) | BPF_SRC(insn->code);

Tbh, I think this should be done in do_misc_fixups(),
mixing it with context handling in convert_ctx_accesses()
seems a bit confusing.

  reply	other threads:[~2024-02-10  1:13 UTC|newest]

Thread overview: 112+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-09  4:05 [PATCH v2 bpf-next 00/20] bpf: Introduce BPF arena Alexei Starovoitov
2024-02-09  4:05 ` [PATCH v2 bpf-next 01/20] bpf: Allow kfuncs return 'void *' Alexei Starovoitov
2024-02-10  6:49   ` Kumar Kartikeya Dwivedi
2024-02-09  4:05 ` [PATCH v2 bpf-next 02/20] bpf: Recognize '__map' suffix in kfunc arguments Alexei Starovoitov
2024-02-10  6:52   ` Kumar Kartikeya Dwivedi
2024-02-09  4:05 ` [PATCH v2 bpf-next 03/20] bpf: Plumb get_unmapped_area() callback into bpf_map_ops Alexei Starovoitov
2024-02-10  0:06   ` kernel test robot
2024-02-10  0:17   ` kernel test robot
2024-02-10  7:04   ` Kumar Kartikeya Dwivedi
2024-02-10  9:06   ` kernel test robot
2024-02-09  4:05 ` [PATCH v2 bpf-next 04/20] mm: Expose vmap_pages_range() to the rest of the kernel Alexei Starovoitov
2024-02-10  7:04   ` Kumar Kartikeya Dwivedi
2024-02-14  8:36   ` Christoph Hellwig
2024-02-14 20:53     ` Alexei Starovoitov
2024-02-15  6:58       ` Christoph Hellwig
2024-02-15 20:50         ` Alexei Starovoitov
2024-02-15 21:26           ` Linus Torvalds
2024-02-16  1:34           ` Alexei Starovoitov
2024-02-16  9:31           ` Christoph Hellwig
2024-02-16 16:54             ` Alexei Starovoitov
2024-02-16 17:18               ` Uladzislau Rezki
2024-02-18  2:06                 ` Alexei Starovoitov
2024-02-20  6:57               ` Christoph Hellwig
2024-02-09  4:05 ` [PATCH v2 bpf-next 05/20] bpf: Introduce bpf_arena Alexei Starovoitov
2024-02-09 20:36   ` David Vernet
2024-02-10  4:38     ` Alexei Starovoitov
2024-02-10  7:40   ` Kumar Kartikeya Dwivedi
2024-02-12 18:21     ` Alexei Starovoitov
2024-02-12 15:56   ` Barret Rhoden
2024-02-12 18:23     ` Alexei Starovoitov
2024-02-13 23:14   ` Andrii Nakryiko
2024-02-13 23:29     ` Alexei Starovoitov
2024-02-14  0:03       ` Andrii Nakryiko
2024-02-14  0:14         ` Alexei Starovoitov
2024-02-09  4:05 ` [PATCH v2 bpf-next 06/20] bpf: Disasm support for cast_kern/user instructions Alexei Starovoitov
2024-02-10  7:41   ` Kumar Kartikeya Dwivedi
2024-02-09  4:05 ` [PATCH v2 bpf-next 07/20] bpf: Add x86-64 JIT support for PROBE_MEM32 pseudo instructions Alexei Starovoitov
2024-02-09 17:20   ` Eduard Zingerman
2024-02-13 22:20     ` Alexei Starovoitov
2024-02-10  6:48   ` Kumar Kartikeya Dwivedi
2024-02-13 22:00     ` Alexei Starovoitov
2024-02-09  4:05 ` [PATCH v2 bpf-next 08/20] bpf: Add x86-64 JIT support for bpf_cast_user instruction Alexei Starovoitov
2024-02-10  1:15   ` Eduard Zingerman
2024-02-10  8:40   ` Kumar Kartikeya Dwivedi
2024-02-13 22:28     ` Alexei Starovoitov
2024-02-09  4:05 ` [PATCH v2 bpf-next 09/20] bpf: Recognize cast_kern/user instructions in the verifier Alexei Starovoitov
2024-02-10  1:13   ` Eduard Zingerman [this message]
2024-02-13  2:58     ` Alexei Starovoitov
2024-02-13 12:01       ` Eduard Zingerman
2024-02-09  4:05 ` [PATCH v2 bpf-next 10/20] bpf: Recognize btf_decl_tag("arg:arena") as PTR_TO_ARENA Alexei Starovoitov
2024-02-10  8:51   ` Kumar Kartikeya Dwivedi
2024-02-13 23:14   ` Andrii Nakryiko
2024-02-14  0:26     ` Alexei Starovoitov
2024-02-09  4:05 ` [PATCH v2 bpf-next 11/20] libbpf: Add __arg_arena to bpf_helpers.h Alexei Starovoitov
2024-02-10  8:51   ` Kumar Kartikeya Dwivedi
2024-02-13 23:14   ` Andrii Nakryiko
2024-02-09  4:06 ` [PATCH v2 bpf-next 12/20] libbpf: Add support for bpf_arena Alexei Starovoitov
2024-02-10  7:16   ` Kumar Kartikeya Dwivedi
2024-02-12 19:11     ` Andrii Nakryiko
2024-02-12 22:29       ` Kumar Kartikeya Dwivedi
2024-02-12 18:12   ` Eduard Zingerman
2024-02-12 20:14     ` Alexei Starovoitov
2024-02-12 20:21       ` Eduard Zingerman
2024-02-13 23:15   ` Andrii Nakryiko
2024-02-14  0:32     ` Alexei Starovoitov
2024-02-09  4:06 ` [PATCH v2 bpf-next 13/20] libbpf: Allow specifying 64-bit integers in map BTF Alexei Starovoitov
2024-02-12 18:58   ` Eduard Zingerman
2024-02-13 23:15   ` Andrii Nakryiko
2024-02-14  0:47     ` Alexei Starovoitov
2024-02-14  0:51       ` Andrii Nakryiko
2024-02-09  4:06 ` [PATCH v2 bpf-next 14/20] libbpf: Recognize __arena global varaibles Alexei Starovoitov
2024-02-13  0:34   ` Eduard Zingerman
2024-02-13  0:44     ` Alexei Starovoitov
2024-02-13  0:49       ` Eduard Zingerman
2024-02-13  2:08         ` Alexei Starovoitov
2024-02-13 12:48           ` Eduard Zingerman
2024-02-13 23:11   ` Eduard Zingerman
2024-02-13 23:17     ` Andrii Nakryiko
2024-02-13 23:36       ` Eduard Zingerman
2024-02-14  0:09         ` Andrii Nakryiko
2024-02-14  0:16           ` Eduard Zingerman
2024-02-14  0:29             ` Andrii Nakryiko
2024-02-14  1:24           ` Alexei Starovoitov
2024-02-14 17:24             ` Andrii Nakryiko
2024-02-15 23:22               ` Andrii Nakryiko
2024-02-16  2:45                 ` Alexei Starovoitov
2024-02-16  4:51                   ` Andrii Nakryiko
2024-02-14  1:02     ` Alexei Starovoitov
2024-02-14 15:10       ` Eduard Zingerman
2024-02-13 23:15   ` Andrii Nakryiko
2024-02-09  4:06 ` [PATCH v2 bpf-next 15/20] bpf: Tell bpf programs kernel's PAGE_SIZE Alexei Starovoitov
2024-02-10  8:52   ` Kumar Kartikeya Dwivedi
2024-02-09  4:06 ` [PATCH v2 bpf-next 16/20] bpf: Add helper macro bpf_arena_cast() Alexei Starovoitov
2024-02-10  8:54   ` Kumar Kartikeya Dwivedi
2024-02-13 22:35     ` Alexei Starovoitov
2024-02-14 16:47       ` Eduard Zingerman
2024-02-14 17:45         ` Alexei Starovoitov
2024-02-09  4:06 ` [PATCH v2 bpf-next 17/20] selftests/bpf: Add unit tests for bpf_arena_alloc/free_pages Alexei Starovoitov
2024-02-09 23:14   ` David Vernet
2024-02-10  4:35     ` Alexei Starovoitov
2024-02-10  7:03       ` Kumar Kartikeya Dwivedi
2024-02-13 23:19         ` Alexei Starovoitov
2024-02-12 16:48       ` David Vernet
2024-02-09  4:06 ` [PATCH v2 bpf-next 18/20] selftests/bpf: Add bpf_arena_list test Alexei Starovoitov
2024-02-09  4:06 ` [PATCH v2 bpf-next 19/20] selftests/bpf: Add bpf_arena_htab test Alexei Starovoitov
2024-02-09  4:06 ` [PATCH v2 bpf-next 20/20] selftests/bpf: Convert simple page_frag allocator to per-cpu Alexei Starovoitov
2024-02-10  7:05   ` Kumar Kartikeya Dwivedi
2024-02-14  1:37     ` Alexei Starovoitov
2024-02-12 14:14 ` [PATCH v2 bpf-next 00/20] bpf: Introduce BPF arena David Hildenbrand
2024-02-12 18:14   ` Alexei Starovoitov
2024-02-13 10:35     ` David Hildenbrand
2024-02-12 17:36 ` Barret Rhoden

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=ed656ef900c33cb1bf9ffb06d0f4f59d7708e29c.camel@gmail.com \
    --to=eddyz87@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=alexei.starovoitov@gmail.com \
    --cc=andrii@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=brho@google.com \
    --cc=daniel@iogearbox.net \
    --cc=hannes@cmpxchg.org \
    --cc=hch@infradead.org \
    --cc=kernel-team@fb.com \
    --cc=linux-mm@kvack.org \
    --cc=lstoakes@gmail.com \
    --cc=memxor@gmail.com \
    --cc=tj@kernel.org \
    --cc=urezki@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 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.