All of lore.kernel.org
 help / color / mirror / Atom feed
From: John Fastabend <john.fastabend@gmail.com>
To: alexei.starovoitov@gmail.com, daniel@iogearbox.net, andrii@kernel.org
Cc: john.fastabend@gmail.com, bpf@vger.kernel.org, netdev@vger.kernel.org
Subject: [PATCH bpf 1/2] bpf, sockmap: Attach map progs to psock early for feature probes
Date: Fri, 19 Nov 2021 10:14:17 -0800	[thread overview]
Message-ID: <20211119181418.353932-2-john.fastabend@gmail.com> (raw)
In-Reply-To: <20211119181418.353932-1-john.fastabend@gmail.com>

When a TCP socket is added to a sock map we look at the programs attached
to the map to determine what proto op hooks need to be changed. Before
the patch in the 'fixes' tag there were only two categories -- the empty
set of programs or a TX policy. In any case the base set handled the
receive case.

After the fix we have an optimized program for receive that closes a
small, but possible, race on receive. This program is loaded only
when the map the psock is being added to includes a RX policy.
Otherwise, the race is not possible so we don't need to handle the
race condition.

In order for the call to sk_psock_init() to correctly evaluate the
above conditions all progs need to be set in the psock before the
call. However, in the current code this is not the case. We end
up evaluating the requirements on the old prog state. If your psock
is attached to multiple maps -- for example a tx map and rx map --
then the second update would pull in the correct maps. But, the
other pattern with a single rx enabled map the correct receive
hooks are not used. The result is the race fixed by the patch in
the fixes tag below may still be seen in this case.

To fix we simply set all psock->progs before doing the call into
sock_map_init((). With this the init() call gets the full list
of programs and chooses the correct proto ops on the first
iteration instead of requiring the second update to pull them
in. This fixes the race case when only a single map is used.

Fixes: c5d2177a72a16 ("bpf, sockmap: Fix race in ingress receive verdict with redirect to self")
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
 net/core/sock_map.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/net/core/sock_map.c b/net/core/sock_map.c
index f39ef79ced67..9b528c644fb7 100644
--- a/net/core/sock_map.c
+++ b/net/core/sock_map.c
@@ -282,6 +282,12 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk)
 
 	if (msg_parser)
 		psock_set_prog(&psock->progs.msg_parser, msg_parser);
+	if (stream_parser)
+		psock_set_prog(&psock->progs.stream_parser, stream_parser);
+	if (stream_verdict)
+		psock_set_prog(&psock->progs.stream_verdict, stream_verdict);
+	if (skb_verdict)
+		psock_set_prog(&psock->progs.skb_verdict, skb_verdict);
 
 	ret = sock_map_init_proto(sk, psock);
 	if (ret < 0)
@@ -292,14 +298,10 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk)
 		ret = sk_psock_init_strp(sk, psock);
 		if (ret)
 			goto out_unlock_drop;
-		psock_set_prog(&psock->progs.stream_verdict, stream_verdict);
-		psock_set_prog(&psock->progs.stream_parser, stream_parser);
 		sk_psock_start_strp(sk, psock);
 	} else if (!stream_parser && stream_verdict && !psock->saved_data_ready) {
-		psock_set_prog(&psock->progs.stream_verdict, stream_verdict);
 		sk_psock_start_verdict(sk,psock);
 	} else if (!stream_verdict && skb_verdict && !psock->saved_data_ready) {
-		psock_set_prog(&psock->progs.skb_verdict, skb_verdict);
 		sk_psock_start_verdict(sk, psock);
 	}
 	write_unlock_bh(&sk->sk_callback_lock);
-- 
2.33.0


  reply	other threads:[~2021-11-19 18:14 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-19 18:14 [PATCH bpf 0/2] sockmap fix for test_map failure John Fastabend
2021-11-19 18:14 ` John Fastabend [this message]
2021-11-19 18:14 ` [PATCH bpf 2/2] bpf, sockmap: Re-evaluate proto ops when psock is removed from sockmap John Fastabend
2021-11-20  0:00 ` [PATCH bpf 0/2] sockmap fix for test_map failure patchwork-bot+netdevbpf

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=20211119181418.353932-2-john.fastabend@gmail.com \
    --to=john.fastabend@gmail.com \
    --cc=alexei.starovoitov@gmail.com \
    --cc=andrii@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --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 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.