From: Jakub Sitnicki <jakub@cloudflare.com>
To: Lorenz Bauer <lmb@cloudflare.com>
Cc: John Fastabend <john.fastabend@gmail.com>,
Daniel Borkmann <daniel@iogearbox.net>,
"David S. Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>,
Alexei Starovoitov <ast@kernel.org>,
Martin KaFai Lau <kafai@fb.com>, Song Liu <songliubraving@fb.com>,
Yonghong Song <yhs@fb.com>, Andrii Nakryiko <andriin@fb.com>,
kernel-team@cloudflare.com, netdev@vger.kernel.org,
bpf@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH bpf] bpf: sockmap: check update requirements after locking
Date: Fri, 07 Feb 2020 11:56:38 +0100 [thread overview]
Message-ID: <87y2temzrt.fsf@cloudflare.com> (raw)
In-Reply-To: <20200207103713.28175-1-lmb@cloudflare.com>
On Fri, Feb 07, 2020 at 11:37 AM CET, Lorenz Bauer wrote:
> It's currently possible to insert sockets in unexpected states into
> a sockmap, due to a TOCTTOU when updating the map from a syscall.
> sock_map_update_elem checks that sk->sk_state == TCP_ESTABLISHED,
> locks the socket and then calls sock_map_update_common. At this
> point, the socket may have transitioned into another state, and
> the earlier assumptions don't hold anymore. Crucially, it's
> conceivable (though very unlikely) that a socket has become unhashed.
> This breaks the sockmap's assumption that it will get a callback
> via sk->sk_prot->unhash.
>
> Fix this by checking the (fixed) sk_type and sk_protocol without the
> lock, followed by a locked check of sk_state.
>
> Unfortunately it's not possible to push the check down into
> sock_(map|hash)_update_common, since BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB
> run before the socket has transitioned from TCP_SYN_RECV into
> TCP_ESTABLISHED.
>
> Signed-off-by: Lorenz Bauer <lmb@cloudflare.com>
> Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface")
> ---
> net/core/sock_map.c | 16 ++++++++++------
> 1 file changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/net/core/sock_map.c b/net/core/sock_map.c
> index 8998e356f423..36a2433e183f 100644
> --- a/net/core/sock_map.c
> +++ b/net/core/sock_map.c
> @@ -416,14 +416,16 @@ static int sock_map_update_elem(struct bpf_map *map, void *key,
> ret = -EINVAL;
> goto out;
> }
> - if (!sock_map_sk_is_suitable(sk) ||
> - sk->sk_state != TCP_ESTABLISHED) {
> + if (!sock_map_sk_is_suitable(sk)) {
> ret = -EOPNOTSUPP;
> goto out;
> }
>
> sock_map_sk_acquire(sk);
> - ret = sock_map_update_common(map, idx, sk, flags);
> + if (sk->sk_state != TCP_ESTABLISHED)
> + ret = -EOPNOTSUPP;
> + else
> + ret = sock_map_update_common(map, idx, sk, flags);
> sock_map_sk_release(sk);
> out:
> fput(sock->file);
> @@ -739,14 +741,16 @@ static int sock_hash_update_elem(struct bpf_map *map, void *key,
> ret = -EINVAL;
> goto out;
> }
> - if (!sock_map_sk_is_suitable(sk) ||
> - sk->sk_state != TCP_ESTABLISHED) {
> + if (!sock_map_sk_is_suitable(sk)) {
> ret = -EOPNOTSUPP;
> goto out;
> }
>
> sock_map_sk_acquire(sk);
> - ret = sock_hash_update_common(map, key, sk, flags);
> + if (sk->sk_state != TCP_ESTABLISHED)
> + ret = -EOPNOTSUPP;
> + else
> + ret = sock_hash_update_common(map, key, sk, flags);
> sock_map_sk_release(sk);
> out:
> fput(sock->file);
> --
> 2.20.1
Thanks for fixing this, Lorenz. I'll adapt socket state checks on update
in "Extend SOCKMAP to store listening sockets" series accordingly.
Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
next prev parent reply other threads:[~2020-02-07 10:56 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-07 10:37 [PATCH bpf] bpf: sockmap: check update requirements after locking Lorenz Bauer
2020-02-07 10:56 ` Jakub Sitnicki [this message]
2020-02-07 21:50 ` 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=87y2temzrt.fsf@cloudflare.com \
--to=jakub@cloudflare.com \
--cc=andriin@fb.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=kernel-team@cloudflare.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lmb@cloudflare.com \
--cc=netdev@vger.kernel.org \
--cc=songliubraving@fb.com \
--cc=yhs@fb.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.