Skip to content
This repository has been archived by the owner on Apr 18, 2024. It is now read-only.

Commit

Permalink
mptcp: Ensure proper free'ing of master_sk upon failure
Browse files Browse the repository at this point in the history
We might have inet_opt set from the meta, but inet_sock_destruct will try to free it.
We need to set it to NULL to prevent a use-after-free.

We need to make sure that the socket is in SOCK_DEAD, thus call
sock_orphan() as inet_sock_destruct checks for SOCK_DEAD. Same for
TCP_CLOSE.

The lock has been taken in sk_clone_lock(). Drop it!

Fixes: Zero-day bug
Signed-off-by: Christoph Paasch <cpaasch@apple.com>
Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
  • Loading branch information
cpaasch authored and matttbe committed Mar 8, 2019
1 parent 80100cd commit 8e81c81
Showing 1 changed file with 17 additions and 10 deletions.
27 changes: 17 additions & 10 deletions net/mptcp/mptcp_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1146,15 +1146,13 @@ static int mptcp_alloc_mpcb(struct sock *meta_sk, __u64 remote_key,
master_sk = sk_clone_lock(meta_sk, GFP_ATOMIC | __GFP_ZERO);
meta_tp->is_master_sk = 0;
if (!master_sk)
return -ENOBUFS;
goto err_alloc_master;

master_tp = tcp_sk(master_sk);

mpcb = kmem_cache_zalloc(mptcp_cb_cache, GFP_ATOMIC);
if (!mpcb) {
sk_free(master_sk);
return -ENOBUFS;
}
if (!mpcb)
goto err_alloc_mpcb;

/* Store the mptcp version agreed on initial handshake */
mpcb->mptcp_ver = mptcp_ver;
Expand Down Expand Up @@ -1212,11 +1210,7 @@ static int mptcp_alloc_mpcb(struct sock *meta_sk, __u64 remote_key,
spin_unlock(&mptcp_tk_hashlock);
rcu_read_unlock_bh();

inet_put_port(master_sk);
kmem_cache_free(mptcp_cb_cache, mpcb);
sk_free(master_sk);

return -ENOBUFS;
goto err_insert_token;
}
__mptcp_hash_insert(meta_tp, mpcb->mptcp_loc_token);

Expand Down Expand Up @@ -1360,6 +1354,19 @@ static int mptcp_alloc_mpcb(struct sock *meta_sk, __u64 remote_key,
__func__, mpcb->mptcp_loc_token);

return 0;

err_insert_token:
kmem_cache_free(mptcp_cb_cache, mpcb);

err_alloc_mpcb:
inet_sk(master_sk)->inet_opt = NULL;
master_sk->sk_state = TCP_CLOSE;
sock_orphan(master_sk);
bh_unlock_sock(master_sk);
sk_free(master_sk);

err_alloc_master:
return -ENOBUFS;
}

/* Called without holding lock on mpcb */
Expand Down

0 comments on commit 8e81c81

Please sign in to comment.