mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-26 13:44:15 +08:00
mptcp: Protect subflow socket options before connection completes
Userspace should not be able to directly manipulate subflow socket options before a connection is established since it is not yet known if it will be an MPTCP subflow or a TCP fallback subflow. TCP fallback subflows can be more directly controlled by userspace because they are regular TCP connections, while MPTCP subflow sockets need to be configured for the specific needs of MPTCP. Use the same logic as sendmsg/recvmsg to ensure that socket option calls are only passed through to known TCP fallback subflows. Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
6f08e98d62
commit
b6e4a1aeeb
@ -755,60 +755,50 @@ static int mptcp_setsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, unsigned int optlen)
|
||||
{
|
||||
struct mptcp_sock *msk = mptcp_sk(sk);
|
||||
int ret = -EOPNOTSUPP;
|
||||
struct socket *ssock;
|
||||
struct sock *ssk;
|
||||
|
||||
pr_debug("msk=%p", msk);
|
||||
|
||||
/* @@ the meaning of setsockopt() when the socket is connected and
|
||||
* there are multiple subflows is not defined.
|
||||
* there are multiple subflows is not yet defined. It is up to the
|
||||
* MPTCP-level socket to configure the subflows until the subflow
|
||||
* is in TCP fallback, when TCP socket options are passed through
|
||||
* to the one remaining subflow.
|
||||
*/
|
||||
lock_sock(sk);
|
||||
ssock = __mptcp_socket_create(msk, MPTCP_SAME_STATE);
|
||||
if (IS_ERR(ssock)) {
|
||||
release_sock(sk);
|
||||
return ret;
|
||||
}
|
||||
ssock = __mptcp_tcp_fallback(msk);
|
||||
if (ssock)
|
||||
return tcp_setsockopt(ssock->sk, level, optname, optval,
|
||||
optlen);
|
||||
|
||||
ssk = ssock->sk;
|
||||
sock_hold(ssk);
|
||||
release_sock(sk);
|
||||
|
||||
ret = tcp_setsockopt(ssk, level, optname, optval, optlen);
|
||||
sock_put(ssk);
|
||||
|
||||
return ret;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int mptcp_getsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int __user *option)
|
||||
{
|
||||
struct mptcp_sock *msk = mptcp_sk(sk);
|
||||
int ret = -EOPNOTSUPP;
|
||||
struct socket *ssock;
|
||||
struct sock *ssk;
|
||||
|
||||
pr_debug("msk=%p", msk);
|
||||
|
||||
/* @@ the meaning of getsockopt() when the socket is connected and
|
||||
* there are multiple subflows is not defined.
|
||||
/* @@ the meaning of setsockopt() when the socket is connected and
|
||||
* there are multiple subflows is not yet defined. It is up to the
|
||||
* MPTCP-level socket to configure the subflows until the subflow
|
||||
* is in TCP fallback, when socket options are passed through
|
||||
* to the one remaining subflow.
|
||||
*/
|
||||
lock_sock(sk);
|
||||
ssock = __mptcp_socket_create(msk, MPTCP_SAME_STATE);
|
||||
if (IS_ERR(ssock)) {
|
||||
release_sock(sk);
|
||||
return ret;
|
||||
}
|
||||
ssock = __mptcp_tcp_fallback(msk);
|
||||
if (ssock)
|
||||
return tcp_getsockopt(ssock->sk, level, optname, optval,
|
||||
option);
|
||||
|
||||
ssk = ssock->sk;
|
||||
sock_hold(ssk);
|
||||
release_sock(sk);
|
||||
|
||||
ret = tcp_getsockopt(ssk, level, optname, optval, option);
|
||||
sock_put(ssk);
|
||||
|
||||
return ret;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int mptcp_get_port(struct sock *sk, unsigned short snum)
|
||||
|
Loading…
Reference in New Issue
Block a user