Skip to content

Commit b6e4a1a

Browse files
mjmartineaudavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6f08e98 commit b6e4a1a

File tree

1 file changed

+19
-29
lines changed

1 file changed

+19
-29
lines changed

net/mptcp/protocol.c

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -755,60 +755,50 @@ static int mptcp_setsockopt(struct sock *sk, int level, int optname,
755755
char __user *optval, unsigned int optlen)
756756
{
757757
struct mptcp_sock *msk = mptcp_sk(sk);
758-
int ret = -EOPNOTSUPP;
759758
struct socket *ssock;
760-
struct sock *ssk;
761759

762760
pr_debug("msk=%p", msk);
763761

764762
/* @@ the meaning of setsockopt() when the socket is connected and
765-
* there are multiple subflows is not defined.
763+
* there are multiple subflows is not yet defined. It is up to the
764+
* MPTCP-level socket to configure the subflows until the subflow
765+
* is in TCP fallback, when TCP socket options are passed through
766+
* to the one remaining subflow.
766767
*/
767768
lock_sock(sk);
768-
ssock = __mptcp_socket_create(msk, MPTCP_SAME_STATE);
769-
if (IS_ERR(ssock)) {
770-
release_sock(sk);
771-
return ret;
772-
}
769+
ssock = __mptcp_tcp_fallback(msk);
770+
if (ssock)
771+
return tcp_setsockopt(ssock->sk, level, optname, optval,
772+
optlen);
773773

774-
ssk = ssock->sk;
775-
sock_hold(ssk);
776774
release_sock(sk);
777775

778-
ret = tcp_setsockopt(ssk, level, optname, optval, optlen);
779-
sock_put(ssk);
780-
781-
return ret;
776+
return -EOPNOTSUPP;
782777
}
783778

784779
static int mptcp_getsockopt(struct sock *sk, int level, int optname,
785780
char __user *optval, int __user *option)
786781
{
787782
struct mptcp_sock *msk = mptcp_sk(sk);
788-
int ret = -EOPNOTSUPP;
789783
struct socket *ssock;
790-
struct sock *ssk;
791784

792785
pr_debug("msk=%p", msk);
793786

794-
/* @@ the meaning of getsockopt() when the socket is connected and
795-
* there are multiple subflows is not defined.
787+
/* @@ the meaning of setsockopt() when the socket is connected and
788+
* there are multiple subflows is not yet defined. It is up to the
789+
* MPTCP-level socket to configure the subflows until the subflow
790+
* is in TCP fallback, when socket options are passed through
791+
* to the one remaining subflow.
796792
*/
797793
lock_sock(sk);
798-
ssock = __mptcp_socket_create(msk, MPTCP_SAME_STATE);
799-
if (IS_ERR(ssock)) {
800-
release_sock(sk);
801-
return ret;
802-
}
794+
ssock = __mptcp_tcp_fallback(msk);
795+
if (ssock)
796+
return tcp_getsockopt(ssock->sk, level, optname, optval,
797+
option);
803798

804-
ssk = ssock->sk;
805-
sock_hold(ssk);
806799
release_sock(sk);
807800

808-
ret = tcp_getsockopt(ssk, level, optname, optval, option);
809-
sock_put(ssk);
810-
811-
return ret;
801+
return -EOPNOTSUPP;
812802
}
813803

814804
static int mptcp_get_port(struct sock *sk, unsigned short snum)

0 commit comments

Comments
 (0)