Commit e42f1ac6 authored by Florian Westphal's avatar Florian Westphal Committed by David S. Miller

mptcp: do not inherit inet proto ops

We need to initialise the struct ourselves, else we expose tcp-specific
callbacks such as tcp_splice_read which will then trigger splat because
the socket is an mptcp one:

BUG: KASAN: slab-out-of-bounds in tcp_mstamp_refresh+0x80/0xa0 net/ipv4/tcp_output.c:57
Write of size 8 at addr ffff888116aa21d0 by task syz-executor.0/5478

CPU: 1 PID: 5478 Comm: syz-executor.0 Not tainted 5.5.0-rc6 #3
Call Trace:
 tcp_mstamp_refresh+0x80/0xa0 net/ipv4/tcp_output.c:57
 tcp_rcv_space_adjust+0x72/0x7f0 net/ipv4/tcp_input.c:612
 tcp_read_sock+0x622/0x990 net/ipv4/tcp.c:1674
 tcp_splice_read+0x20b/0xb40 net/ipv4/tcp.c:791
 do_splice+0x1259/0x1560 fs/splice.c:1205

To prevent build error with ipv6, add the recv/sendmsg function
declaration to ipv6.h.  The functions are already accessible "thanks"
to retpoline related work, but they are currently only made visible
by socket.c specific INDIRECT_CALLABLE macros.
Reported-by: default avatarChristoph Paasch <cpaasch@apple.com>
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 08a45c59
...@@ -1113,6 +1113,9 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); ...@@ -1113,6 +1113,9 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
int inet6_hash_connect(struct inet_timewait_death_row *death_row, int inet6_hash_connect(struct inet_timewait_death_row *death_row,
struct sock *sk); struct sock *sk);
int inet6_sendmsg(struct socket *sock, struct msghdr *msg, size_t size);
int inet6_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
int flags);
/* /*
* reassembly.c * reassembly.c
......
...@@ -1163,7 +1163,31 @@ static int mptcp_shutdown(struct socket *sock, int how) ...@@ -1163,7 +1163,31 @@ static int mptcp_shutdown(struct socket *sock, int how)
return ret; return ret;
} }
static struct proto_ops mptcp_stream_ops; static const struct proto_ops mptcp_stream_ops = {
.family = PF_INET,
.owner = THIS_MODULE,
.release = inet_release,
.bind = mptcp_bind,
.connect = mptcp_stream_connect,
.socketpair = sock_no_socketpair,
.accept = mptcp_stream_accept,
.getname = mptcp_v4_getname,
.poll = mptcp_poll,
.ioctl = inet_ioctl,
.gettstamp = sock_gettstamp,
.listen = mptcp_listen,
.shutdown = mptcp_shutdown,
.setsockopt = sock_common_setsockopt,
.getsockopt = sock_common_getsockopt,
.sendmsg = inet_sendmsg,
.recvmsg = inet_recvmsg,
.mmap = sock_no_mmap,
.sendpage = inet_sendpage,
#ifdef CONFIG_COMPAT
.compat_setsockopt = compat_sock_common_setsockopt,
.compat_getsockopt = compat_sock_common_getsockopt,
#endif
};
static struct inet_protosw mptcp_protosw = { static struct inet_protosw mptcp_protosw = {
.type = SOCK_STREAM, .type = SOCK_STREAM,
...@@ -1176,14 +1200,6 @@ static struct inet_protosw mptcp_protosw = { ...@@ -1176,14 +1200,6 @@ static struct inet_protosw mptcp_protosw = {
void mptcp_proto_init(void) void mptcp_proto_init(void)
{ {
mptcp_prot.h.hashinfo = tcp_prot.h.hashinfo; mptcp_prot.h.hashinfo = tcp_prot.h.hashinfo;
mptcp_stream_ops = inet_stream_ops;
mptcp_stream_ops.bind = mptcp_bind;
mptcp_stream_ops.connect = mptcp_stream_connect;
mptcp_stream_ops.poll = mptcp_poll;
mptcp_stream_ops.accept = mptcp_stream_accept;
mptcp_stream_ops.getname = mptcp_v4_getname;
mptcp_stream_ops.listen = mptcp_listen;
mptcp_stream_ops.shutdown = mptcp_shutdown;
mptcp_subflow_init(); mptcp_subflow_init();
...@@ -1194,7 +1210,32 @@ void mptcp_proto_init(void) ...@@ -1194,7 +1210,32 @@ void mptcp_proto_init(void)
} }
#if IS_ENABLED(CONFIG_MPTCP_IPV6) #if IS_ENABLED(CONFIG_MPTCP_IPV6)
static struct proto_ops mptcp_v6_stream_ops; static const struct proto_ops mptcp_v6_stream_ops = {
.family = PF_INET6,
.owner = THIS_MODULE,
.release = inet6_release,
.bind = mptcp_bind,
.connect = mptcp_stream_connect,
.socketpair = sock_no_socketpair,
.accept = mptcp_stream_accept,
.getname = mptcp_v6_getname,
.poll = mptcp_poll,
.ioctl = inet6_ioctl,
.gettstamp = sock_gettstamp,
.listen = mptcp_listen,
.shutdown = mptcp_shutdown,
.setsockopt = sock_common_setsockopt,
.getsockopt = sock_common_getsockopt,
.sendmsg = inet6_sendmsg,
.recvmsg = inet6_recvmsg,
.mmap = sock_no_mmap,
.sendpage = inet_sendpage,
#ifdef CONFIG_COMPAT
.compat_setsockopt = compat_sock_common_setsockopt,
.compat_getsockopt = compat_sock_common_getsockopt,
#endif
};
static struct proto mptcp_v6_prot; static struct proto mptcp_v6_prot;
static void mptcp_v6_destroy(struct sock *sk) static void mptcp_v6_destroy(struct sock *sk)
...@@ -1226,15 +1267,6 @@ int mptcp_proto_v6_init(void) ...@@ -1226,15 +1267,6 @@ int mptcp_proto_v6_init(void)
if (err) if (err)
return err; return err;
mptcp_v6_stream_ops = inet6_stream_ops;
mptcp_v6_stream_ops.bind = mptcp_bind;
mptcp_v6_stream_ops.connect = mptcp_stream_connect;
mptcp_v6_stream_ops.poll = mptcp_poll;
mptcp_v6_stream_ops.accept = mptcp_stream_accept;
mptcp_v6_stream_ops.getname = mptcp_v6_getname;
mptcp_v6_stream_ops.listen = mptcp_listen;
mptcp_v6_stream_ops.shutdown = mptcp_shutdown;
err = inet6_register_protosw(&mptcp_v6_protosw); err = inet6_register_protosw(&mptcp_v6_protosw);
if (err) if (err)
proto_unregister(&mptcp_v6_prot); proto_unregister(&mptcp_v6_prot);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment