|
Jiri Slaby |
ef65b8 |
From: Xin Long <lucien.xin@gmail.com>
|
|
Jiri Slaby |
ef65b8 |
Subject: sctp: change sctp_prot .no_autobind with true
|
|
Michal Kubecek |
12c818 |
Patch-mainline: v5.4-rc4
|
|
Jiri Slaby |
ef65b8 |
Git-commit: 63dfb7938b13fa2c2fbcb45f34d065769eb09414
|
|
Michal Kubecek |
12c818 |
References: networking-stable-19_10_24 bsc#1158082
|
|
Jiri Slaby |
ef65b8 |
|
|
Jiri Slaby |
ef65b8 |
syzbot reported a memory leak:
|
|
Jiri Slaby |
ef65b8 |
|
|
Jiri Slaby |
ef65b8 |
BUG: memory leak, unreferenced object 0xffff888120b3d380 (size 64):
|
|
Jiri Slaby |
ef65b8 |
backtrace:
|
|
Jiri Slaby |
ef65b8 |
|
|
Jiri Slaby |
ef65b8 |
[...] slab_alloc mm/slab.c:3319 [inline]
|
|
Jiri Slaby |
ef65b8 |
[...] kmem_cache_alloc+0x13f/0x2c0 mm/slab.c:3483
|
|
Jiri Slaby |
ef65b8 |
[...] sctp_bucket_create net/sctp/socket.c:8523 [inline]
|
|
Jiri Slaby |
ef65b8 |
[...] sctp_get_port_local+0x189/0x5a0 net/sctp/socket.c:8270
|
|
Jiri Slaby |
ef65b8 |
[...] sctp_do_bind+0xcc/0x200 net/sctp/socket.c:402
|
|
Jiri Slaby |
ef65b8 |
[...] sctp_bindx_add+0x4b/0xd0 net/sctp/socket.c:497
|
|
Jiri Slaby |
ef65b8 |
[...] sctp_setsockopt_bindx+0x156/0x1b0 net/sctp/socket.c:1022
|
|
Jiri Slaby |
ef65b8 |
[...] sctp_setsockopt net/sctp/socket.c:4641 [inline]
|
|
Jiri Slaby |
ef65b8 |
[...] sctp_setsockopt+0xaea/0x2dc0 net/sctp/socket.c:4611
|
|
Jiri Slaby |
ef65b8 |
[...] sock_common_setsockopt+0x38/0x50 net/core/sock.c:3147
|
|
Jiri Slaby |
ef65b8 |
[...] __sys_setsockopt+0x10f/0x220 net/socket.c:2084
|
|
Jiri Slaby |
ef65b8 |
[...] __do_sys_setsockopt net/socket.c:2100 [inline]
|
|
Jiri Slaby |
ef65b8 |
|
|
Jiri Slaby |
ef65b8 |
It was caused by when sending msgs without binding a port, in the path:
|
|
Jiri Slaby |
ef65b8 |
inet_sendmsg() -> inet_send_prepare() -> inet_autobind() ->
|
|
Jiri Slaby |
ef65b8 |
.get_port/sctp_get_port(), sp->bind_hash will be set while bp->port is
|
|
Jiri Slaby |
ef65b8 |
not. Later when binding another port by sctp_setsockopt_bindx(), a new
|
|
Jiri Slaby |
ef65b8 |
bucket will be created as bp->port is not set.
|
|
Jiri Slaby |
ef65b8 |
|
|
Jiri Slaby |
ef65b8 |
sctp's autobind is supposed to call sctp_autobind() where it does all
|
|
Jiri Slaby |
ef65b8 |
things including setting bp->port. Since sctp_autobind() is called in
|
|
Jiri Slaby |
ef65b8 |
sctp_sendmsg() if the sk is not yet bound, it should have skipped the
|
|
Jiri Slaby |
ef65b8 |
auto bind.
|
|
Jiri Slaby |
ef65b8 |
|
|
Jiri Slaby |
ef65b8 |
THis patch is to avoid calling inet_autobind() in inet_send_prepare()
|
|
Jiri Slaby |
ef65b8 |
by changing sctp_prot .no_autobind with true, also remove the unused
|
|
Jiri Slaby |
ef65b8 |
.get_port.
|
|
Jiri Slaby |
ef65b8 |
|
|
Jiri Slaby |
ef65b8 |
Reported-by: syzbot+d44f7bbebdea49dbc84a@syzkaller.appspotmail.com
|
|
Jiri Slaby |
ef65b8 |
Signed-off-by: Xin Long <lucien.xin@gmail.com>
|
|
Jiri Slaby |
ef65b8 |
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
|
|
Jiri Slaby |
ef65b8 |
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Jiri Slaby |
ef65b8 |
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
|
Michal Kubecek |
12c818 |
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
|
|
Michal Kubecek |
12c818 |
|
|
Michal Kubecek |
12c818 |
SLE15: we need to check no_autobind socket flag in inet_dgram_connect() as,
|
|
Michal Kubecek |
12c818 |
unlike in mainline, SCTP still uses this function.
|
|
Michal Kubecek |
12c818 |
|
|
Jiri Slaby |
ef65b8 |
---
|
|
Michal Kubecek |
12c818 |
net/ipv4/af_inet.c | 3 ++-
|
|
Michal Kubecek |
12c818 |
net/sctp/socket.c | 4 ++--
|
|
Michal Kubecek |
12c818 |
2 files changed, 4 insertions(+), 3 deletions(-)
|
|
Jiri Slaby |
ef65b8 |
|
|
Michal Kubecek |
12c818 |
--- a/net/ipv4/af_inet.c
|
|
Michal Kubecek |
12c818 |
+++ b/net/ipv4/af_inet.c
|
|
Michal Kubecek |
12c818 |
@@ -535,7 +535,8 @@ int inet_dgram_connect(struct socket *sock, struct sockaddr *uaddr,
|
|
Michal Kubecek |
12c818 |
if (uaddr->sa_family == AF_UNSPEC)
|
|
Michal Kubecek |
12c818 |
return sk->sk_prot->disconnect(sk, flags);
|
|
Michal Kubecek |
12c818 |
|
|
Michal Kubecek |
12c818 |
- if (!inet_sk(sk)->inet_num && inet_autobind(sk))
|
|
Michal Kubecek |
12c818 |
+ if (!inet_sk(sk)->inet_num && !sk->sk_prot->no_autobind &&
|
|
Michal Kubecek |
12c818 |
+ inet_autobind(sk))
|
|
Michal Kubecek |
12c818 |
return -EAGAIN;
|
|
Michal Kubecek |
12c818 |
return sk->sk_prot->connect(sk, uaddr, addr_len);
|
|
Michal Kubecek |
12c818 |
}
|
|
Jiri Slaby |
ef65b8 |
--- a/net/sctp/socket.c
|
|
Jiri Slaby |
ef65b8 |
+++ b/net/sctp/socket.c
|
|
Jiri Slaby |
ef65b8 |
@@ -8240,7 +8240,7 @@ struct proto sctp_prot = {
|
|
Jiri Slaby |
ef65b8 |
.backlog_rcv = sctp_backlog_rcv,
|
|
Jiri Slaby |
ef65b8 |
.hash = sctp_hash,
|
|
Jiri Slaby |
ef65b8 |
.unhash = sctp_unhash,
|
|
Jiri Slaby |
ef65b8 |
- .get_port = sctp_get_port,
|
|
Jiri Slaby |
ef65b8 |
+ .no_autobind = true,
|
|
Jiri Slaby |
ef65b8 |
.obj_size = sizeof(struct sctp_sock),
|
|
Jiri Slaby |
ef65b8 |
.sysctl_mem = sysctl_sctp_mem,
|
|
Jiri Slaby |
ef65b8 |
.sysctl_rmem = sysctl_sctp_rmem,
|
|
Jiri Slaby |
ef65b8 |
@@ -8279,7 +8279,7 @@ struct proto sctpv6_prot = {
|
|
Jiri Slaby |
ef65b8 |
.backlog_rcv = sctp_backlog_rcv,
|
|
Jiri Slaby |
ef65b8 |
.hash = sctp_hash,
|
|
Jiri Slaby |
ef65b8 |
.unhash = sctp_unhash,
|
|
Jiri Slaby |
ef65b8 |
- .get_port = sctp_get_port,
|
|
Jiri Slaby |
ef65b8 |
+ .no_autobind = true,
|
|
Jiri Slaby |
ef65b8 |
.obj_size = sizeof(struct sctp6_sock),
|
|
Jiri Slaby |
ef65b8 |
.sysctl_mem = sysctl_sctp_mem,
|
|
Jiri Slaby |
ef65b8 |
.sysctl_rmem = sysctl_sctp_rmem,
|