All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: sdf@google.com
Cc: bpf@vger.kernel.org, Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Martin KaFai Lau <martin.lau@kernel.org>,
	Joanne Koong <joannelkoong@gmail.com>,
	David Vernet <void@manifault.com>
Subject: Re: [PATCH bpf-next v1 04/13] bpf: Rework check_func_arg_reg_off
Date: Wed, 19 Oct 2022 11:54:51 +0530	[thread overview]
Message-ID: <20221019062451.z7ho6keovbjsn7wv@apollo> (raw)
In-Reply-To: <Y08gyUs+HCBYw0Q5@google.com>

On Wed, Oct 19, 2022 at 03:25:21AM IST, sdf@google.com wrote:
> On 10/18, Kumar Kartikeya Dwivedi wrote:
> > While check_func_arg_reg_off is the place which performs generic checks
> > needed by various candidates of reg->type, there is some handling for
> > special cases, like ARG_PTR_TO_DYNPTR, OBJ_RELEASE, and
> > ARG_PTR_TO_ALLOC_MEM.
>
> > This commit aims to streamline these special cases and instead leave
> > other things up to argument type specific code to handle.
>
> > This is done primarily for two reasons: associating back reg->type to
> > its argument leaves room for the list getting out of sync when a new
> > reg->type is supported by an arg_type.
>
> > The other case is ARG_PTR_TO_ALLOC_MEM. The problem there is something
> > we already handle, whenever a release argument is expected, it should
> > be passed as the pointer that was received from the acquire function.
> > Hence zero fixed and variable offset.
>
> > There is nothing special about ARG_PTR_TO_ALLOC_MEM, where technically
> > its target register type PTR_TO_MEM | MEM_ALLOC can already be passed
> > with non-zero offset to other helper functions, which makes sense.
>
> > Hence, lift the arg_type_is_release check for reg->off and cover all
> > possible register types, instead of duplicating the same kind of check
> > twice for current OBJ_RELEASE arg_types (alloc_mem and ptr_to_btf_id).
>
> > Finally, for the release argument, arg_type_is_dynptr is the special
> > case, where we go to actual object being freed through the dynptr, so
> > the offset of the pointer still needs to allow fixed and variable offset
> > and process_dynptr_func will verify them later for the release argument
> > case as well.
>
> > Finally, since check_func_arg_reg_off is meant to be generic, move
> > dynptr specific check into process_dynptr_func.
>
> > Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> > ---
> >   kernel/bpf/verifier.c                         | 55 +++++++++++++++----
> >   .../testing/selftests/bpf/verifier/ringbuf.c  |  2 +-
> >   2 files changed, 44 insertions(+), 13 deletions(-)
>
> > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> > index a49b95c1af1b..a8c277e51d63 100644
> > --- a/kernel/bpf/verifier.c
> > +++ b/kernel/bpf/verifier.c
> > @@ -5654,6 +5654,14 @@ int process_dynptr_func(struct bpf_verifier_env
> > *env, int regno,
> >   		return -EFAULT;
> >   	}
>
> > +	/* CONST_PTR_TO_DYNPTR has fixed and variable offset as zero, ensured by
> > +	 * check_func_arg_reg_off, so this is only needed for PTR_TO_STACK.
> > +	 */
> > +	if (reg->off % BPF_REG_SIZE) {
> > +		verbose(env, "cannot pass in dynptr at an offset\n");
> > +		return -EINVAL;
> > +	}
>
> This is what I'm missing here and in the original code as well, maybe you
> can clarify?
>
> "if (reg->off & BPF_REG_SIZE)" here vs "if (reg->off)" below. What's the
> difference?
>

That second one happens earlier in check_func_arg_reg_off, this check happens
later.

Usually when we have release arguments, we want pointer to object unmodified.
So the fixed and variable offset must be 0. The check_func_arg_reg_off checks
ensure that. But PTR_TO_STACK in case of dynptr release functions point to the
dynptr object on the stack which has to be released.

In this case fp will have some fixed offset. So we make an exception for it and
fallback to normal checks for PTR_TO_STACK.

Later when we come here, we reach the function for two kinds of registers,
CONST_PTR_TO_DYNPTR and PTR_TO_STACK. PTR_TO_STACK reg->off must be aligned
to 8-byte alignment since we want to find stack slot index (each representing 8
byte slot) of the dynptr to operate on it.

For CONST_PTR_TO_DYNPTR it directly points to dynptr with 0 offset, which
check_func_arg_reg_off already ensures for it.

Note that this reg->off check is actually broken, the correct one is in patch 6
which takes into account the variable offset.

You can consider check_func_arg_reg_off to only do high level checks which are
common for all helpers, and later processing builds upon those guarantees and
does further checking.

  reply	other threads:[~2022-10-19  6:25 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-18 13:59 [PATCH bpf-next v1 00/13] Fixes for dynptr Kumar Kartikeya Dwivedi
2022-10-18 13:59 ` [PATCH bpf-next v1 01/13] bpf: Refactor ARG_PTR_TO_DYNPTR checks into process_dynptr_func Kumar Kartikeya Dwivedi
2022-10-18 19:45   ` David Vernet
2022-10-19  6:04     ` Kumar Kartikeya Dwivedi
2022-10-19 15:26       ` David Vernet
2022-10-19 22:59   ` Joanne Koong
2022-10-20  0:55     ` Kumar Kartikeya Dwivedi
2022-10-18 13:59 ` [PATCH bpf-next v1 02/13] bpf: Rework process_dynptr_func Kumar Kartikeya Dwivedi
2022-10-18 23:16   ` David Vernet
2022-10-19  6:18     ` Kumar Kartikeya Dwivedi
2022-10-19 16:05       ` David Vernet
2022-10-20  1:09         ` Kumar Kartikeya Dwivedi
2022-10-18 13:59 ` [PATCH bpf-next v1 03/13] bpf: Rename confusingly named RET_PTR_TO_ALLOC_MEM Kumar Kartikeya Dwivedi
2022-10-18 21:38   ` sdf
2022-10-19  6:19     ` Kumar Kartikeya Dwivedi
2022-11-07 22:35   ` Joanne Koong
2022-11-07 23:12     ` Kumar Kartikeya Dwivedi
2022-10-18 13:59 ` [PATCH bpf-next v1 04/13] bpf: Rework check_func_arg_reg_off Kumar Kartikeya Dwivedi
2022-10-18 21:55   ` sdf
2022-10-19  6:24     ` Kumar Kartikeya Dwivedi [this message]
2022-11-07 23:17   ` Joanne Koong
2022-11-08 18:22     ` Kumar Kartikeya Dwivedi
2022-10-18 13:59 ` [PATCH bpf-next v1 05/13] bpf: Fix state pruning for STACK_DYNPTR stack slots Kumar Kartikeya Dwivedi
2022-11-08 20:22   ` Joanne Koong
2022-11-09 18:39     ` Kumar Kartikeya Dwivedi
2022-11-10  0:41       ` Joanne Koong
2022-10-18 13:59 ` [PATCH bpf-next v1 06/13] bpf: Fix missing var_off check for ARG_PTR_TO_DYNPTR Kumar Kartikeya Dwivedi
2022-10-19 18:52   ` Alexei Starovoitov
2022-10-20  1:04     ` Kumar Kartikeya Dwivedi
2022-10-20  2:13       ` Alexei Starovoitov
2022-10-20  2:40         ` Kumar Kartikeya Dwivedi
2022-10-20  2:56           ` Alexei Starovoitov
2022-10-20  3:23             ` Kumar Kartikeya Dwivedi
2022-10-21  0:46               ` Alexei Starovoitov
2022-10-21  1:53                 ` Kumar Kartikeya Dwivedi
2022-10-18 13:59 ` [PATCH bpf-next v1 07/13] bpf: Fix partial dynptr stack slot reads/writes Kumar Kartikeya Dwivedi
2022-10-21 22:50   ` Joanne Koong
2022-10-21 22:57     ` Joanne Koong
2022-10-22  4:08     ` Kumar Kartikeya Dwivedi
2022-11-03 14:07       ` Joanne Koong
2022-11-04 22:14         ` Andrii Nakryiko
2022-11-04 23:02           ` Kumar Kartikeya Dwivedi
2022-11-04 23:08             ` Andrii Nakryiko
2022-10-18 13:59 ` [PATCH bpf-next v1 08/13] bpf: Use memmove for bpf_dynptr_{read,write} Kumar Kartikeya Dwivedi
2022-10-21 18:12   ` Joanne Koong
2022-10-18 13:59 ` [PATCH bpf-next v1 09/13] selftests/bpf: Add test for dynptr reinit in user_ringbuf callback Kumar Kartikeya Dwivedi
2022-10-19 16:59   ` David Vernet
2022-10-18 13:59 ` [PATCH bpf-next v1 10/13] selftests/bpf: Add dynptr pruning tests Kumar Kartikeya Dwivedi
2022-10-18 13:59 ` [PATCH bpf-next v1 11/13] selftests/bpf: Add dynptr var_off tests Kumar Kartikeya Dwivedi
2022-10-18 13:59 ` [PATCH bpf-next v1 12/13] selftests/bpf: Add dynptr partial slot overwrite tests Kumar Kartikeya Dwivedi
2022-10-18 13:59 ` [PATCH bpf-next v1 13/13] selftests/bpf: Add dynptr helper tests Kumar Kartikeya Dwivedi
2023-10-31  7:05 ` CVE-2023-39191 - Dynptr fixes - reg Nandhini Rengaraj
2023-10-31  7:13   ` Greg KH
2023-10-31  7:57   ` Shung-Hsi Yu

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=20221019062451.z7ho6keovbjsn7wv@apollo \
    --to=memxor@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=joannelkoong@gmail.com \
    --cc=martin.lau@kernel.org \
    --cc=sdf@google.com \
    --cc=void@manifault.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.