mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Yonghong Song <yhs@fb.com>
To: Lorenz Bauer <lmb@cloudflare.com>
Cc: Jakub Sitnicki <jakub@cloudflare.com>,
	John Fastabend <john.fastabend@gmail.com>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	kernel-team <kernel-team@cloudflare.com>,
	Networking <netdev@vger.kernel.org>, bpf <bpf@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH bpf-next v2 4/6] bpf: override the meaning of ARG_PTR_TO_MAP_VALUE for sockmap and sockhash
Date: Thu, 20 Aug 2020 09:18:57 -0700	[thread overview]
Message-ID: <2d167605-df64-29c8-f817-d2602cb9d57f@fb.com> (raw)
In-Reply-To: <CACAyw98gaWmpJT-LPhqKbKgaPG9s=aNU=K2Db1144dihFHzXJA@mail.gmail.com>



On 8/20/20 9:15 AM, Lorenz Bauer wrote:
> On Thu, 20 Aug 2020 at 17:10, Yonghong Song <yhs@fb.com> wrote:
>>
>>
>>
>> On 8/20/20 6:57 AM, Lorenz Bauer wrote:
>>> The verifier assumes that map values are simple blobs of memory, and
>>> therefore treats ARG_PTR_TO_MAP_VALUE, etc. as such. However, there are
>>> map types where this isn't true. For example, sockmap and sockhash store
>>> sockets. In general this isn't a big problem: we can just
>>> write helpers that explicitly requests PTR_TO_SOCKET instead of
>>> ARG_PTR_TO_MAP_VALUE.
>>>
>>> The one exception are the standard map helpers like map_update_elem,
>>> map_lookup_elem, etc. Here it would be nice we could overload the
>>> function prototype for different kinds of maps. Unfortunately, this
>>> isn't entirely straight forward:
>>> We only know the type of the map once we have resolved meta->map_ptr
>>> in check_func_arg. This means we can't swap out the prototype
>>> in check_helper_call until we're half way through the function.
>>>
>>> Instead, modify check_func_arg to treat ARG_PTR_TO_MAP_VALUE* to
>>> mean "the native type for the map" instead of "pointer to memory"
>>> for sockmap and sockhash. This means we don't have to modify the
>>> function prototype at all
>>>
>>> Signed-off-by: Lorenz Bauer <lmb@cloudflare.com>
>>> ---
>>>    kernel/bpf/verifier.c | 37 +++++++++++++++++++++++++++++++++++++
>>>    1 file changed, 37 insertions(+)
>>>
>>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>>> index b6ccfce3bf4c..24feec515d3e 100644
>>> --- a/kernel/bpf/verifier.c
>>> +++ b/kernel/bpf/verifier.c
>>> @@ -3872,6 +3872,35 @@ static int int_ptr_type_to_size(enum bpf_arg_type type)
>>>        return -EINVAL;
>>>    }
>>>
>>> +static int resolve_map_arg_type(struct bpf_verifier_env *env,
>>> +                              const struct bpf_call_arg_meta *meta,
>>> +                              enum bpf_arg_type *arg_type)
>>> +{
>>> +     if (!meta->map_ptr) {
>>> +             /* kernel subsystem misconfigured verifier */
>>> +             verbose(env, "invalid map_ptr to access map->type\n");
>>> +             return -EACCES;
>>> +     }
>>> +
>>> +     switch (meta->map_ptr->map_type) {
>>> +     case BPF_MAP_TYPE_SOCKMAP:
>>> +     case BPF_MAP_TYPE_SOCKHASH:
>>> +             if (*arg_type == ARG_PTR_TO_MAP_VALUE) {
>>> +                     *arg_type = ARG_PTR_TO_SOCKET;
>>> +             } else if (*arg_type == ARG_PTR_TO_MAP_VALUE_OR_NULL) {
>>> +                     *arg_type = ARG_PTR_TO_SOCKET_OR_NULL;
>>
>> Is this *arg_type == ARG_PTR_TO_MAP_VALUE_OR_NULL possible with
>> current implementation?
> 
> No, the only user is bpf_sk_storage_get and friends which requires
> BPF_MAP_TYPE_SK_STORAGE.
> I seemed to make sense to map ARG_PTR_TO_MAP_VALUE_OR_NULL, but I can
> remove it as
> well if you prefer. Do you think this is dangerous?

It is not dangerous, but is misleading. People looking at code may
think it is possible but actually it is not. So I prefer you remove it.

> 
>>
>> If not, we can remove this "else if" and return -EINVAL, right?
>>
>>> +             } else {
>>> +                     verbose(env, "invalid arg_type for sockmap/sockhash\n");
>>> +                     return -EINVAL;
>>> +             }
>>> +             break;
>>> +
>>> +     default:
>>> +             break;
>>> +     }
>>> +     return 0;
>>> +}
>>> +
>>>    static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
>>>                          struct bpf_call_arg_meta *meta,
>>>                          const struct bpf_func_proto *fn)
>>> @@ -3904,6 +3933,14 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
>>>                return -EACCES;
>>>        }
>>>
>>> +     if (arg_type == ARG_PTR_TO_MAP_VALUE ||
>>> +         arg_type == ARG_PTR_TO_UNINIT_MAP_VALUE ||
>>> +         arg_type == ARG_PTR_TO_MAP_VALUE_OR_NULL) {
>>> +             err = resolve_map_arg_type(env, meta, &arg_type);
>>
>> I am okay with this to cover all MAP_VALUE types with func
>> name resolve_map_arg_type as a generic helper.
>>
>>> +             if (err)
>>> +                     return err;
>>> +     }
>>> +
>>>        if (arg_type == ARG_PTR_TO_MAP_KEY ||
>>>            arg_type == ARG_PTR_TO_MAP_VALUE ||
>>>            arg_type == ARG_PTR_TO_UNINIT_MAP_VALUE ||
>>>
> 
> 
> 

  reply	other threads:[~2020-08-20 16:19 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20200820135729.135783-1-lmb@cloudflare.com>
2020-08-20 13:57 ` [PATCH bpf-next v2 1/6] net: sk_msg: simplify sk_psock initialization Lorenz Bauer
2020-08-20 13:57 ` [PATCH bpf-next v2 2/6] bpf: sockmap: merge sockmap and sockhash update functions Lorenz Bauer
2020-08-20 13:57 ` [PATCH bpf-next v2 3/6] bpf: sockmap: call sock_map_update_elem directly Lorenz Bauer
2020-08-20 13:57 ` [PATCH bpf-next v2 4/6] bpf: override the meaning of ARG_PTR_TO_MAP_VALUE for sockmap and sockhash Lorenz Bauer
2020-08-20 16:10   ` Yonghong Song
2020-08-20 16:15     ` Lorenz Bauer
2020-08-20 16:18       ` Yonghong Song [this message]
2020-08-20 13:57 ` [PATCH bpf-next v2 5/6] bpf: sockmap: allow update from BPF Lorenz Bauer
2020-08-20 13:57 ` [PATCH bpf-next v2 6/6] selftests: bpf: test sockmap " Lorenz Bauer

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=2d167605-df64-29c8-f817-d2602cb9d57f@fb.com \
    --to=yhs@fb.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=jakub@cloudflare.com \
    --cc=john.fastabend@gmail.com \
    --cc=kernel-team@cloudflare.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lmb@cloudflare.com \
    --cc=netdev@vger.kernel.org \
    /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

all inboxes | Powered by JetHome®