Skip to content

Commit e42f1ac

Browse files
Florian Westphaldavem330
authored andcommitted
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: Christoph Paasch <[email protected]> Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Mat Martineau <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 08a45c5 commit e42f1ac

File tree

2 files changed

+54
-19
lines changed

2 files changed

+54
-19
lines changed

include/net/ipv6.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,9 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
11131113

11141114
int inet6_hash_connect(struct inet_timewait_death_row *death_row,
11151115
struct sock *sk);
1116+
int inet6_sendmsg(struct socket *sock, struct msghdr *msg, size_t size);
1117+
int inet6_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
1118+
int flags);
11161119

11171120
/*
11181121
* reassembly.c

net/mptcp/protocol.c

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,7 +1163,31 @@ static int mptcp_shutdown(struct socket *sock, int how)
11631163
return ret;
11641164
}
11651165

1166-
static struct proto_ops mptcp_stream_ops;
1166+
static const struct proto_ops mptcp_stream_ops = {
1167+
.family = PF_INET,
1168+
.owner = THIS_MODULE,
1169+
.release = inet_release,
1170+
.bind = mptcp_bind,
1171+
.connect = mptcp_stream_connect,
1172+
.socketpair = sock_no_socketpair,
1173+
.accept = mptcp_stream_accept,
1174+
.getname = mptcp_v4_getname,
1175+
.poll = mptcp_poll,
1176+
.ioctl = inet_ioctl,
1177+
.gettstamp = sock_gettstamp,
1178+
.listen = mptcp_listen,
1179+
.shutdown = mptcp_shutdown,
1180+
.setsockopt = sock_common_setsockopt,
1181+
.getsockopt = sock_common_getsockopt,
1182+
.sendmsg = inet_sendmsg,
1183+
.recvmsg = inet_recvmsg,
1184+
.mmap = sock_no_mmap,
1185+
.sendpage = inet_sendpage,
1186+
#ifdef CONFIG_COMPAT
1187+
.compat_setsockopt = compat_sock_common_setsockopt,
1188+
.compat_getsockopt = compat_sock_common_getsockopt,
1189+
#endif
1190+
};
11671191

11681192
static struct inet_protosw mptcp_protosw = {
11691193
.type = SOCK_STREAM,
@@ -1176,14 +1200,6 @@ static struct inet_protosw mptcp_protosw = {
11761200
void mptcp_proto_init(void)
11771201
{
11781202
mptcp_prot.h.hashinfo = tcp_prot.h.hashinfo;
1179-
mptcp_stream_ops = inet_stream_ops;
1180-
mptcp_stream_ops.bind = mptcp_bind;
1181-
mptcp_stream_ops.connect = mptcp_stream_connect;
1182-
mptcp_stream_ops.poll = mptcp_poll;
1183-
mptcp_stream_ops.accept = mptcp_stream_accept;
1184-
mptcp_stream_ops.getname = mptcp_v4_getname;
1185-
mptcp_stream_ops.listen = mptcp_listen;
1186-
mptcp_stream_ops.shutdown = mptcp_shutdown;
11871203

11881204
mptcp_subflow_init();
11891205

@@ -1194,7 +1210,32 @@ void mptcp_proto_init(void)
11941210
}
11951211

11961212
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
1197-
static struct proto_ops mptcp_v6_stream_ops;
1213+
static const struct proto_ops mptcp_v6_stream_ops = {
1214+
.family = PF_INET6,
1215+
.owner = THIS_MODULE,
1216+
.release = inet6_release,
1217+
.bind = mptcp_bind,
1218+
.connect = mptcp_stream_connect,
1219+
.socketpair = sock_no_socketpair,
1220+
.accept = mptcp_stream_accept,
1221+
.getname = mptcp_v6_getname,
1222+
.poll = mptcp_poll,
1223+
.ioctl = inet6_ioctl,
1224+
.gettstamp = sock_gettstamp,
1225+
.listen = mptcp_listen,
1226+
.shutdown = mptcp_shutdown,
1227+
.setsockopt = sock_common_setsockopt,
1228+
.getsockopt = sock_common_getsockopt,
1229+
.sendmsg = inet6_sendmsg,
1230+
.recvmsg = inet6_recvmsg,
1231+
.mmap = sock_no_mmap,
1232+
.sendpage = inet_sendpage,
1233+
#ifdef CONFIG_COMPAT
1234+
.compat_setsockopt = compat_sock_common_setsockopt,
1235+
.compat_getsockopt = compat_sock_common_getsockopt,
1236+
#endif
1237+
};
1238+
11981239
static struct proto mptcp_v6_prot;
11991240

12001241
static void mptcp_v6_destroy(struct sock *sk)
@@ -1226,15 +1267,6 @@ int mptcp_proto_v6_init(void)
12261267
if (err)
12271268
return err;
12281269

1229-
mptcp_v6_stream_ops = inet6_stream_ops;
1230-
mptcp_v6_stream_ops.bind = mptcp_bind;
1231-
mptcp_v6_stream_ops.connect = mptcp_stream_connect;
1232-
mptcp_v6_stream_ops.poll = mptcp_poll;
1233-
mptcp_v6_stream_ops.accept = mptcp_stream_accept;
1234-
mptcp_v6_stream_ops.getname = mptcp_v6_getname;
1235-
mptcp_v6_stream_ops.listen = mptcp_listen;
1236-
mptcp_v6_stream_ops.shutdown = mptcp_shutdown;
1237-
12381270
err = inet6_register_protosw(&mptcp_v6_protosw);
12391271
if (err)
12401272
proto_unregister(&mptcp_v6_prot);

0 commit comments

Comments
 (0)