| From foo@baz Thu 24 Oct 2019 09:55:34 PM EDT |
| From: Xin Long <lucien.xin@gmail.com> |
| Date: Tue, 15 Oct 2019 15:24:38 +0800 |
| Subject: sctp: change sctp_prot .no_autobind with true |
| |
| From: Xin Long <lucien.xin@gmail.com> |
| |
| [ Upstream commit 63dfb7938b13fa2c2fbcb45f34d065769eb09414 ] |
| |
| syzbot reported a memory leak: |
| |
| BUG: memory leak, unreferenced object 0xffff888120b3d380 (size 64): |
| backtrace: |
| |
| [...] slab_alloc mm/slab.c:3319 [inline] |
| [...] kmem_cache_alloc+0x13f/0x2c0 mm/slab.c:3483 |
| [...] sctp_bucket_create net/sctp/socket.c:8523 [inline] |
| [...] sctp_get_port_local+0x189/0x5a0 net/sctp/socket.c:8270 |
| [...] sctp_do_bind+0xcc/0x200 net/sctp/socket.c:402 |
| [...] sctp_bindx_add+0x4b/0xd0 net/sctp/socket.c:497 |
| [...] sctp_setsockopt_bindx+0x156/0x1b0 net/sctp/socket.c:1022 |
| [...] sctp_setsockopt net/sctp/socket.c:4641 [inline] |
| [...] sctp_setsockopt+0xaea/0x2dc0 net/sctp/socket.c:4611 |
| [...] sock_common_setsockopt+0x38/0x50 net/core/sock.c:3147 |
| [...] __sys_setsockopt+0x10f/0x220 net/socket.c:2084 |
| [...] __do_sys_setsockopt net/socket.c:2100 [inline] |
| |
| It was caused by when sending msgs without binding a port, in the path: |
| inet_sendmsg() -> inet_send_prepare() -> inet_autobind() -> |
| .get_port/sctp_get_port(), sp->bind_hash will be set while bp->port is |
| not. Later when binding another port by sctp_setsockopt_bindx(), a new |
| bucket will be created as bp->port is not set. |
| |
| sctp's autobind is supposed to call sctp_autobind() where it does all |
| things including setting bp->port. Since sctp_autobind() is called in |
| sctp_sendmsg() if the sk is not yet bound, it should have skipped the |
| auto bind. |
| |
| THis patch is to avoid calling inet_autobind() in inet_send_prepare() |
| by changing sctp_prot .no_autobind with true, also remove the unused |
| .get_port. |
| |
| Reported-by: syzbot+d44f7bbebdea49dbc84a@syzkaller.appspotmail.com |
| Signed-off-by: Xin Long <lucien.xin@gmail.com> |
| Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/sctp/socket.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/net/sctp/socket.c |
| +++ b/net/sctp/socket.c |
| @@ -7453,7 +7453,7 @@ struct proto sctp_prot = { |
| .backlog_rcv = sctp_backlog_rcv, |
| .hash = sctp_hash, |
| .unhash = sctp_unhash, |
| - .get_port = sctp_get_port, |
| + .no_autobind = true, |
| .obj_size = sizeof(struct sctp_sock), |
| .sysctl_mem = sysctl_sctp_mem, |
| .sysctl_rmem = sysctl_sctp_rmem, |
| @@ -7492,7 +7492,7 @@ struct proto sctpv6_prot = { |
| .backlog_rcv = sctp_backlog_rcv, |
| .hash = sctp_hash, |
| .unhash = sctp_unhash, |
| - .get_port = sctp_get_port, |
| + .no_autobind = true, |
| .obj_size = sizeof(struct sctp6_sock), |
| .sysctl_mem = sysctl_sctp_mem, |
| .sysctl_rmem = sysctl_sctp_rmem, |