diff mbox series

[net] sctp: change sctp_prot .no_autobind with true

Message ID 06beb8a9ceaec9224a507b58d3477da106c5f0cd.1571124278.git.lucien.xin@gmail.com
State Accepted
Delegated to: David Miller
Headers show
Series [net] sctp: change sctp_prot .no_autobind with true | expand

Commit Message

Xin Long Oct. 15, 2019, 7:24 a.m. UTC
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>
---
 net/sctp/socket.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Marcelo Ricardo Leitner Oct. 15, 2019, 2:35 p.m. UTC | #1
On Tue, Oct 15, 2019 at 03:24:38PM +0800, Xin Long wrote:
> 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>
David Miller Oct. 16, 2019, 3:39 a.m. UTC | #2
From: Xin Long <lucien.xin@gmail.com>
Date: Tue, 15 Oct 2019 15:24:38 +0800

> syzbot reported a memory leak:
> 
>   BUG: memory leak, unreferenced object 0xffff888120b3d380 (size 64):
>   backtrace:
 ...
> 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>

Applied and queued up for -stable.

Xin, in the future please always provide a Fixes: even if it is the
initial kernel repository commit.

Thanks.
Xin Long Oct. 16, 2019, 5:26 a.m. UTC | #3
On Wed, Oct 16, 2019 at 11:39 AM David Miller <davem@davemloft.net> wrote:
>
> From: Xin Long <lucien.xin@gmail.com>
> Date: Tue, 15 Oct 2019 15:24:38 +0800
>
> > syzbot reported a memory leak:
> >
> >   BUG: memory leak, unreferenced object 0xffff888120b3d380 (size 64):
> >   backtrace:
>  ...
> > 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>
>
> Applied and queued up for -stable.
>
> Xin, in the future please always provide a Fixes: even if it is the
> initial kernel repository commit.
Copy, thanks.
diff mbox series

Patch

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 939b8d2..5ca0ec0 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -9500,7 +9500,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),
 	.useroffset  =  offsetof(struct sctp_sock, subscribe),
 	.usersize    =  offsetof(struct sctp_sock, initmsg) -
@@ -9542,7 +9542,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),
 	.useroffset	= offsetof(struct sctp6_sock, sctp.subscribe),
 	.usersize	= offsetof(struct sctp6_sock, sctp.initmsg) -