Message ID | 20180124203541.3172-3-tom@quantonium.net |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
Series | kcm: fix two syzcaller issues | expand |
On Wed, 2018-01-24 at 12:35 -0800, Tom Herbert wrote: > This is needed to prevent sk_user_data being overwritten. > The check is done under the callback lock. This should prevent > a socket from being attached twice to a KCM mux. It also prevents > a socket from being attached for other use cases of sk_user_data > as long as the other cases set sk_user_data under the lock. > Followup work is needed to unify all the use cases of sk_user_data > to use the same locking. > Reviewed-by: Eric Dumazet <edumazet@google.com>
On Wed, 2018-01-24 at 12:35 -0800, Tom Herbert wrote: > This is needed to prevent sk_user_data being overwritten. > The check is done under the callback lock. This should prevent > a socket from being attached twice to a KCM mux. It also prevents > a socket from being attached for other use cases of sk_user_data > as long as the other cases set sk_user_data under the lock. > Followup work is needed to unify all the use cases of sk_user_data > to use the same locking. > > Reported-by: syzbot+114b15f2be420a8886c3@syzkaller.appspotmail.com > Fixes: ab7ac4eb9832 ("kcm: Kernel Connection Multiplexor module") > Signed-off-by: Tom Herbert <tom@quantonium.net> > --- > net/kcm/kcmsock.c | 16 ++++++++++++++-- > 1 file changed, 14 insertions(+), 2 deletions(-) > > diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c > index 7632797fb68e..4a8d407f8902 100644 > --- a/net/kcm/kcmsock.c > +++ b/net/kcm/kcmsock.c > @@ -1410,9 +1410,18 @@ static int kcm_attach(struct socket *sock, struct socket *csock, > return err; > } > > - sock_hold(csk); > - > write_lock_bh(&csk->sk_callback_lock); > + > + /* Check if sk_user_data is aready by KCM or someone else. > + * Must be done under lock to prevent race conditions. > + */ > + if (csk->sk_user_data) { > + write_unlock_bh(&csk->sk_callback_lock); > + strp_done(&psock->strp); Although it seems psock->strp->stopped wont be set ? We should hit WARN_ON(!strp->stopped);
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c index 7632797fb68e..4a8d407f8902 100644 --- a/net/kcm/kcmsock.c +++ b/net/kcm/kcmsock.c @@ -1410,9 +1410,18 @@ static int kcm_attach(struct socket *sock, struct socket *csock, return err; } - sock_hold(csk); - write_lock_bh(&csk->sk_callback_lock); + + /* Check if sk_user_data is aready by KCM or someone else. + * Must be done under lock to prevent race conditions. + */ + if (csk->sk_user_data) { + write_unlock_bh(&csk->sk_callback_lock); + strp_done(&psock->strp); + kmem_cache_free(kcm_psockp, psock); + return -EALREADY; + } + psock->save_data_ready = csk->sk_data_ready; psock->save_write_space = csk->sk_write_space; psock->save_state_change = csk->sk_state_change; @@ -1420,8 +1429,11 @@ static int kcm_attach(struct socket *sock, struct socket *csock, csk->sk_data_ready = psock_data_ready; csk->sk_write_space = psock_write_space; csk->sk_state_change = psock_state_change; + write_unlock_bh(&csk->sk_callback_lock); + sock_hold(csk); + /* Finished initialization, now add the psock to the MUX. */ spin_lock_bh(&mux->lock); head = &mux->psocks;
This is needed to prevent sk_user_data being overwritten. The check is done under the callback lock. This should prevent a socket from being attached twice to a KCM mux. It also prevents a socket from being attached for other use cases of sk_user_data as long as the other cases set sk_user_data under the lock. Followup work is needed to unify all the use cases of sk_user_data to use the same locking. Reported-by: syzbot+114b15f2be420a8886c3@syzkaller.appspotmail.com Fixes: ab7ac4eb9832 ("kcm: Kernel Connection Multiplexor module") Signed-off-by: Tom Herbert <tom@quantonium.net> --- net/kcm/kcmsock.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)