From: sdf@google.com
To: Daniel Borkmann <daniel@iogearbox.net>
Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, davem@davemloft.net,
ast@kernel.org, John Fastabend <john.fastabend@gmail.com>,
Martin KaFai Lau <kafai@fb.com>
Subject: Re: [PATCH bpf-next v2] bpf: bpf_{g,s}etsockopt for struct bpf_sock
Date: Wed, 29 Apr 2020 16:33:12 -0700 [thread overview]
Message-ID: <20200429233312.GB241848@google.com> (raw)
In-Reply-To: <640e7fd3-4059-5ff8-f9ed-09b1becd0f7b@iogearbox.net>
On 04/30, Daniel Borkmann wrote:
> On 4/29/20 7:05 PM, Stanislav Fomichev wrote:
> > Currently, bpf_getsocktop and bpf_setsockopt helpers operate on the
> > 'struct bpf_sock_ops' context in BPF_PROG_TYPE_SOCK_OPS program.
> > Let's generalize them and make the first argument be 'struct bpf_sock'.
> > That way, in the future, we can allow those helpers in more places.
> >
> > BPF_PROG_TYPE_SOCK_OPS still has the existing helpers that operate
> > on 'struct bpf_sock_ops', but we add new bpf_{g,s}etsockopt that work
> > on 'struct bpf_sock'. [Alternatively, for BPF_PROG_TYPE_SOCK_OPS,
> > we can enable them both and teach verifier to pick the right one
> > based on the context (bpf_sock_ops vs bpf_sock).]
> >
> > As an example, let's allow those 'struct bpf_sock' based helpers to
> > be called from the BPF_CGROUP_INET{4,6}_CONNECT hooks. That way
> > we can override CC before the connection is made.
> >
> > v2:
> > * s/BPF_PROG_TYPE_CGROUP_SOCKOPT/BPF_PROG_TYPE_SOCK_OPS/
> >
> > Acked-by: John Fastabend <john.fastabend@gmail.com>
> > Acked-by: Martin KaFai Lau <kafai@fb.com>
> > Signed-off-by: Stanislav Fomichev <sdf@google.com>
> [...]
> > +BPF_CALL_5(bpf_setsockopt, struct sock *, sk,
> > + int, level, int, optname, char *, optval, int, optlen)
> > +{
> > + u32 flags = 0;
> > + return _bpf_setsockopt(sk, level, optname, optval, optlen, flags);
> > +}
> > +
> > +static const struct bpf_func_proto bpf_setsockopt_proto = {
> > + .func = bpf_setsockopt,
> > + .gpl_only = false,
> > + .ret_type = RET_INTEGER,
> > + .arg1_type = ARG_PTR_TO_SOCKET,
> > + .arg2_type = ARG_ANYTHING,
> > + .arg3_type = ARG_ANYTHING,
> > + .arg4_type = ARG_PTR_TO_MEM,
> > + .arg5_type = ARG_CONST_SIZE,
> > +};
> > +
> > +BPF_CALL_5(bpf_getsockopt, struct sock *, sk,
> > + int, level, int, optname, char *, optval, int, optlen)
> > +{
> > + return _bpf_getsockopt(sk, level, optname, optval, optlen);
> > +}
> > +
> > static const struct bpf_func_proto bpf_getsockopt_proto = {
> > .func = bpf_getsockopt,
> > .gpl_only = false,
> > .ret_type = RET_INTEGER,
> > + .arg1_type = ARG_PTR_TO_SOCKET,
> > + .arg2_type = ARG_ANYTHING,
> > + .arg3_type = ARG_ANYTHING,
> > + .arg4_type = ARG_PTR_TO_UNINIT_MEM,
> > + .arg5_type = ARG_CONST_SIZE,
> > +};
> > +
> [...]
> > @@ -6043,6 +6098,22 @@ sock_addr_func_proto(enum bpf_func_id func_id,
> const struct bpf_prog *prog)
> > return &bpf_sk_storage_get_proto;
> > case BPF_FUNC_sk_storage_delete:
> > return &bpf_sk_storage_delete_proto;
> > + case BPF_FUNC_setsockopt:
> > + switch (prog->expected_attach_type) {
> > + case BPF_CGROUP_INET4_CONNECT:
> > + case BPF_CGROUP_INET6_CONNECT:
> > + return &bpf_setsockopt_proto;
> Hm, I'm not sure this is safe. In the sock_addr_func_proto() we also have
> other helpers callable from connect hooks like sk_lookup_{tcp,udp} which
> return a PTR_TO_SOCKET_OR_NULL, and now we can pass those sockets also
> into
> bpf_{get,set}sockopt() helper after lookup to change various sk related
> stuff
> but w/o being under lock. Doesn't the sock_owned_by_me() yell here at
> minimum
> (I'd expect so)?
Ugh, good point, I missed the fact that sk_lookup_{tcp,udp} are there
for sock_addr :-( I can try to do a simple test case to verify
that sock_owned_by_me triggers, but I'm pretty certain it should
(I've been calling bpf_{s,g}etsockopt for context socket so it's quiet).
I don't think there is any helper similar to sock_owned_by_me() that
I can call to verify that the socket is held by current thread
(without the lockdep splat) and bail out?
In this case, is something like adding new PTR_TO_LOCKED_SOCKET_OR_NULL
is the way to go? Any other ideas?
next prev parent reply other threads:[~2020-04-29 23:33 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-29 17:05 [PATCH bpf-next v2] bpf: bpf_{g,s}etsockopt for struct bpf_sock Stanislav Fomichev
2020-04-29 23:08 ` Daniel Borkmann
2020-04-29 23:33 ` sdf [this message]
2020-04-30 2:24 ` Alexei Starovoitov
2020-04-30 14:39 ` Daniel Borkmann
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=20200429233312.GB241848@google.com \
--to=sdf@google.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=john.fastabend@gmail.com \
--cc=kafai@fb.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