summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorCraig Gallek <kraig@google.com>2016-01-19 14:27:08 -0500
committerBruno Martins <bgcngm@gmail.com>2022-10-28 15:39:24 +0100
commit245ee3c907953449f9b399b440e682561c55fefe (patch)
tree18f29a8e1dbf293244b7f47b4755603fc2629a92 /net
parent113fb209854a4a7ee69a704600d1274ea3daeb01 (diff)
soreuseport: fix NULL ptr dereference SO_REUSEPORT after bind
Marc Dionne discovered a NULL pointer dereference when setting SO_REUSEPORT on a socket after it is bound. This patch removes the assumption that at least one socket in the reuseport group is bound with the SO_REUSEPORT option before other bind calls occur. Fixes: e32ea7e74727 ("soreuseport: fast reuseport UDP socket selection") Reported-by: Marc Dionne <marc.c.dionne@gmail.com> Signed-off-by: Craig Gallek <kraig@google.com> Tested-by: Marc Dionne <marc.dionne@auristor.com> Signed-off-by: David S. Miller <davem@davemloft.net> Change-Id: Ie9c2cb3dfae4bf97e3e83756c09a3ed607bcf6f7
Diffstat (limited to 'net')
-rw-r--r--net/core/sock_reuseport.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c
index f8035ca0f288..752ad43d9d2d 100644
--- a/net/core/sock_reuseport.c
+++ b/net/core/sock_reuseport.c
@@ -103,10 +103,17 @@ static void reuseport_free_rcu(struct rcu_head *head)
* @sk2: Socket belonging to the existing reuseport group.
* May return ENOMEM and not add socket to group under memory pressure.
*/
-int reuseport_add_sock(struct sock *sk, const struct sock *sk2)
+int reuseport_add_sock(struct sock *sk, struct sock *sk2)
{
struct sock_reuseport *old_reuse, *reuse;
+ if (!rcu_access_pointer(sk2->sk_reuseport_cb)) {
+ int err = reuseport_alloc(sk2);
+
+ if (err)
+ return err;
+ }
+
spin_lock_bh(&reuseport_lock);
reuse = rcu_dereference_protected(sk2->sk_reuseport_cb,
lockdep_is_held(&reuseport_lock));