Skip to content

Commit 0aee4c2

Browse files
nhormandavem330
authored andcommitted
sctp: Fix double free in sctp_sendmsg_to_asoc
syzbot/kasan detected a double free in sctp_sendmsg_to_asoc: BUG: KASAN: use-after-free in sctp_association_free+0x7b7/0x930 net/sctp/associola.c:332 Read of size 8 at addr ffff8801d8006ae0 by task syzkaller914861/4202 CPU: 1 PID: 4202 Comm: syzkaller914861 Not tainted 4.16.0-rc4+ #258 Hardware name: Google Google Compute Engine/Google Compute Engine 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:17 [inline] dump_stack+0x194/0x24d lib/dump_stack.c:53 print_address_description+0x73/0x250 mm/kasan/report.c:256 kasan_report_error mm/kasan/report.c:354 [inline] kasan_report+0x23c/0x360 mm/kasan/report.c:412 __asan_report_load8_noabort+0x14/0x20 mm/kasan/report.c:433 sctp_association_free+0x7b7/0x930 net/sctp/associola.c:332 sctp_sendmsg+0xc67/0x1a80 net/sctp/socket.c:2075 inet_sendmsg+0x11f/0x5e0 net/ipv4/af_inet.c:763 sock_sendmsg_nosec net/socket.c:629 [inline] sock_sendmsg+0xca/0x110 net/socket.c:639 SYSC_sendto+0x361/0x5c0 net/socket.c:1748 SyS_sendto+0x40/0x50 net/socket.c:1716 do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287 entry_SYSCALL_64_after_hwframe+0x42/0xb7 This was introduced by commit: f84af33 sctp: factor out sctp_sendmsg_to_asoc from sctp_sendmsg As the newly refactored function moved the wait_for_sndbuf call to a point after the association was connected, allowing for peeloff events to occur, which in turn caused wait_for_sndbuf to return -EPIPE which was not caught by the logic that determines if an association should be freed or not. Fix it the easy way by returning the ordering of sctp_primitive_ASSOCIATE and sctp_wait_for_sndbuf to the old order, to ensure that EPIPE will not happen. Tested by myself using the syzbot reproducers with positive results Signed-off-by: Neil Horman <[email protected]> CC: [email protected] CC: Xin Long <[email protected]> Reported-by: [email protected] Reviewed-by: Xin Long <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0c3d5a9 commit 0aee4c2

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

net/sctp/socket.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,6 +1883,19 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,
18831883
goto err;
18841884
}
18851885

1886+
if (asoc->pmtu_pending)
1887+
sctp_assoc_pending_pmtu(asoc);
1888+
1889+
if (sctp_wspace(asoc) < msg_len)
1890+
sctp_prsctp_prune(asoc, sinfo, msg_len - sctp_wspace(asoc));
1891+
1892+
if (!sctp_wspace(asoc)) {
1893+
timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
1894+
err = sctp_wait_for_sndbuf(asoc, &timeo, msg_len);
1895+
if (err)
1896+
goto err;
1897+
}
1898+
18861899
if (sctp_state(asoc, CLOSED)) {
18871900
err = sctp_primitive_ASSOCIATE(net, asoc, NULL);
18881901
if (err)
@@ -1900,19 +1913,6 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,
19001913
pr_debug("%s: we associated primitively\n", __func__);
19011914
}
19021915

1903-
if (asoc->pmtu_pending)
1904-
sctp_assoc_pending_pmtu(asoc);
1905-
1906-
if (sctp_wspace(asoc) < msg_len)
1907-
sctp_prsctp_prune(asoc, sinfo, msg_len - sctp_wspace(asoc));
1908-
1909-
if (!sctp_wspace(asoc)) {
1910-
timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
1911-
err = sctp_wait_for_sndbuf(asoc, &timeo, msg_len);
1912-
if (err)
1913-
goto err;
1914-
}
1915-
19161916
datamsg = sctp_datamsg_from_user(asoc, sinfo, &msg->msg_iter);
19171917
if (IS_ERR(datamsg)) {
19181918
err = PTR_ERR(datamsg);

0 commit comments

Comments
 (0)