diff options
author | David S. Miller <davem@davemloft.net> | 2018-01-24 15:54:31 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-01-24 15:54:31 -0500 |
commit | 88d1d76dca25b135657eda6b93eb1bdbde519d0f (patch) | |
tree | 1541ccbaf77a4b034f515865927e175bb7e00bc0 | |
parent | d3303a65a00c94372ddab831570647488e6c06e2 (diff) | |
parent | e5571240236c5652f3e079b1d5866716a7ad819c (diff) | |
download | linux-88d1d76dca25b135657eda6b93eb1bdbde519d0f.tar.bz2 |
Merge branch 'kcm-fix-two-syzcaller-issues'
Tom Herbert says:
====================
kcm: fix two syzcaller issues
In this patch set:
- Don't allow attaching non-TCP or listener sockets to a KCM mux.
- In kcm_attach Check if sk_user_data is already set. This is
under lock to avoid race conditions. More work is need to make
all of the users of sk_user_data to use the same locking.
- v2
Remove unncessary check for not PF_KCM in kcm_attach (suggested by
Guillaume Nault)
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/kcm/kcmsock.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c index d4e98f20fc2a..4a8d407f8902 100644 --- a/net/kcm/kcmsock.c +++ b/net/kcm/kcmsock.c @@ -1387,8 +1387,13 @@ static int kcm_attach(struct socket *sock, struct socket *csock, if (!csk) return -EINVAL; - /* We must prevent loops or risk deadlock ! */ - if (csk->sk_family == PF_KCM) + /* Only allow TCP sockets to be attached for now */ + if ((csk->sk_family != AF_INET && csk->sk_family != AF_INET6) || + csk->sk_protocol != IPPROTO_TCP) + return -EOPNOTSUPP; + + /* Don't allow listeners or closed sockets */ + if (csk->sk_state == TCP_LISTEN || csk->sk_state == TCP_CLOSE) return -EOPNOTSUPP; psock = kmem_cache_zalloc(kcm_psockp, GFP_KERNEL); @@ -1405,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; @@ -1415,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; |