Commit b4ace4f1 authored by Craig Gallek's avatar Craig Gallek Committed by David S. Miller

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: e32ea7e7 ("soreuseport: fast reuseport UDP socket selection")
Reported-by: default avatarMarc Dionne <marc.c.dionne@gmail.com>
Signed-off-by: default avatarCraig Gallek <kraig@google.com>
Tested-by: default avatarMarc Dionne <marc.dionne@auristor.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 52a82e23
...@@ -16,7 +16,7 @@ struct sock_reuseport { ...@@ -16,7 +16,7 @@ struct sock_reuseport {
}; };
extern int reuseport_alloc(struct sock *sk); extern int reuseport_alloc(struct sock *sk);
extern int reuseport_add_sock(struct sock *sk, const struct sock *sk2); extern int reuseport_add_sock(struct sock *sk, struct sock *sk2);
extern void reuseport_detach_sock(struct sock *sk); extern void reuseport_detach_sock(struct sock *sk);
extern struct sock *reuseport_select_sock(struct sock *sk, extern struct sock *reuseport_select_sock(struct sock *sk,
u32 hash, u32 hash,
......
...@@ -93,10 +93,17 @@ static struct sock_reuseport *reuseport_grow(struct sock_reuseport *reuse) ...@@ -93,10 +93,17 @@ static struct sock_reuseport *reuseport_grow(struct sock_reuseport *reuse)
* @sk2: Socket belonging to the existing reuseport group. * @sk2: Socket belonging to the existing reuseport group.
* May return ENOMEM and not add socket to group under memory pressure. * 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 *reuse; struct sock_reuseport *reuse;
if (!rcu_access_pointer(sk2->sk_reuseport_cb)) {
int err = reuseport_alloc(sk2);
if (err)
return err;
}
spin_lock_bh(&reuseport_lock); spin_lock_bh(&reuseport_lock);
reuse = rcu_dereference_protected(sk2->sk_reuseport_cb, reuse = rcu_dereference_protected(sk2->sk_reuseport_cb,
lockdep_is_held(&reuseport_lock)), lockdep_is_held(&reuseport_lock)),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment