From patchwork Fri Apr 30 18:15:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Long X-Patchwork-Id: 430157 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6C95FC43461 for ; Fri, 30 Apr 2021 18:16:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4B22761459 for ; Fri, 30 Apr 2021 18:16:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231418AbhD3SRE (ORCPT ); Fri, 30 Apr 2021 14:17:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41182 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229990AbhD3SRD (ORCPT ); Fri, 30 Apr 2021 14:17:03 -0400 Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2C3EFC06174A; Fri, 30 Apr 2021 11:16:15 -0700 (PDT) Received: by mail-pj1-x102d.google.com with SMTP id j6-20020a17090adc86b02900cbfe6f2c96so2203340pjv.1; Fri, 30 Apr 2021 11:16:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=xAwWOFvCJDNzLLNmsTsVCzG3dAntmC4sJfm+8QnG4Zw=; b=bS0BXeREqBIKP/WueVHeu5WrNRpVdeZq3Ol11TJyx1fDFBgaSyo2oIFtSGNvD9UY0m WPOAbAC06yodC/ujnR6tWg3ziG3gATmuL2MdfPXNh2Oq2Av412ZXGK6E4owTkayj9H/Z Eedw+rtha8D/nAqSwxPUQg+VnfN6VEDGS10hMcR6KFHiGhp66VVmLi/DorCAHIlktkMX MjwaPReawVmaQohWnWiARsoR7dYycuITm0pRgZKWPOr0VTP6PnwYL4zPTZ6PuhIOyj2G gJCxyKzwQjlihwN88dotbFN35mBhzR+cqI8VIIR/SRXH1js7idjR11lLhzlQ6s/UAfUk CkIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=xAwWOFvCJDNzLLNmsTsVCzG3dAntmC4sJfm+8QnG4Zw=; b=d9e3g1coqfJDgJBmFkzIv88zqX0EW8ZeWCVu1RtdHX71DZyCTL01eLdY6h9L5nvPlc yXVo7RM8Itn/Mo8qpZHEkqyu8aj7MfzI8Z6ada6M+ly5rNaePdSHCsmS/ynJxbbyCosH T/n5rTo6W0kJlOe0x38uf1RfgXnKE+Caqcp9ArvoyHAZPe/AeedJpH3TK0/iy4KJijGd vb8sDAl1wRdpqaAQ08Ls6r7jI8qSzlrd/NsJp9PUdXNq6PF8kxSoSIJsRfUES+6ggDTv Hed+4+UzN7LNyEZ1GKRQxqSTJvsV+HH7mMwyUaH+KtGPUdlEueZLUPIcf7yQ1xrTsd/y +zWA== X-Gm-Message-State: AOAM533wlOLu3W58un5gn1JcUd3Ce/bqmyRzjhy1vF4L+JVUeGuyEZrV BUK2t7jto6ND7AY9N26Koe0gkPqpt5II1ANL X-Google-Smtp-Source: ABdhPJyiaORFJGsqWgpt4JhffQ7TsPQpmN/4toMNYAhcsOR/eXyIu4eluR67TQo/BUSvQ6bAPvs27A== X-Received: by 2002:a17:90a:384b:: with SMTP id l11mr6495188pjf.222.1619806574471; Fri, 30 Apr 2021 11:16:14 -0700 (PDT) Received: from localhost ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id b6sm2731130pfb.27.2021.04.30.11.16.13 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 30 Apr 2021 11:16:14 -0700 (PDT) From: Xin Long To: network dev , linux-sctp@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, Marcelo Ricardo Leitner , jere.leppanen@nokia.com, Alexander Sverdlin Subject: [PATCH net 1/3] sctp: do asoc update earlier in sctp_sf_do_dupcook_a Date: Sat, 1 May 2021 02:15:55 +0800 Message-Id: X-Mailer: git-send-email 2.1.0 In-Reply-To: References: In-Reply-To: References: Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org There's a panic that occurs in a few of envs, the call trace is as below: [] general protection fault, ... 0x29acd70f1000a: 0000 [#1] SMP PTI [] RIP: 0010:sctp_ulpevent_notify_peer_addr_change+0x4b/0x1fa [sctp] [] sctp_assoc_control_transport+0x1b9/0x210 [sctp] [] sctp_do_8_2_transport_strike.isra.16+0x15c/0x220 [sctp] [] sctp_cmd_interpreter.isra.21+0x1231/0x1a10 [sctp] [] sctp_do_sm+0xc3/0x2a0 [sctp] [] sctp_generate_timeout_event+0x81/0xf0 [sctp] This is caused by a transport use-after-free issue. When processing a duplicate COOKIE-ECHO chunk in sctp_sf_do_dupcook_a(), both COOKIE-ACK and SHUTDOWN chunks are allocated with the transort from the new asoc. However, later in the sideeffect machine, the old asoc is used to send them out and old asoc's shutdown_last_sent_to is set to the transport that SHUTDOWN chunk attached to in sctp_cmd_setup_t2(), which actually belongs to the new asoc. After the new_asoc is freed and the old asoc T2 timeout, the old asoc's shutdown_last_sent_to that is already freed would be accessed in sctp_sf_t2_timer_expire(). Thanks Alexander and Jere for helping dig into this issue. To fix it, this patch is to do the asoc update first, then allocate the COOKIE-ACK and SHUTDOWN chunks with the 'updated' old asoc. This would make more sense, as a chunk from an asoc shouldn't be sent out with another asoc. We had fixed quite a few issues caused by this. Fixes: 145cb2f7177d ("sctp: Fix bundling of SHUTDOWN with COOKIE-ACK") Reported-by: Alexander Sverdlin Reported-by: syzbot+bbe538efd1046586f587@syzkaller.appspotmail.com Reported-by: Michal Tesar Signed-off-by: Xin Long --- net/sctp/sm_statefuns.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 7632714..30cb946 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -1852,20 +1852,35 @@ static enum sctp_disposition sctp_sf_do_dupcook_a( SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_ASCONF_QUEUE, SCTP_NULL()); - repl = sctp_make_cookie_ack(new_asoc, chunk); + /* Update the content of current association. */ + if (sctp_assoc_update((struct sctp_association *)asoc, new_asoc)) { + struct sctp_chunk *abort; + + abort = sctp_make_abort(asoc, NULL, sizeof(struct sctp_errhdr)); + if (abort) { + sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0); + sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); + } + sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNABORTED)); + sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, + SCTP_PERR(SCTP_ERROR_RSRC_LOW)); + SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS); + SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB); + goto nomem; + } + + repl = sctp_make_cookie_ack(asoc, chunk); if (!repl) goto nomem; /* Report association restart to upper layer. */ ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_RESTART, 0, - new_asoc->c.sinit_num_ostreams, - new_asoc->c.sinit_max_instreams, + asoc->c.sinit_num_ostreams, + asoc->c.sinit_max_instreams, NULL, GFP_ATOMIC); if (!ev) goto nomem_ev; - /* Update the content of current association. */ - sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc)); sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); if ((sctp_state(asoc, SHUTDOWN_PENDING) || sctp_state(asoc, SHUTDOWN_SENT)) && From patchwork Fri Apr 30 18:15:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Long X-Patchwork-Id: 430156 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 85621C43470 for ; Fri, 30 Apr 2021 18:16:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6B78260BBB for ; Fri, 30 Apr 2021 18:16:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231511AbhD3SRU (ORCPT ); Fri, 30 Apr 2021 14:17:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41262 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231267AbhD3SRT (ORCPT ); Fri, 30 Apr 2021 14:17:19 -0400 Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 86D74C06138D; Fri, 30 Apr 2021 11:16:31 -0700 (PDT) Received: by mail-pf1-x435.google.com with SMTP id i13so2060770pfu.2; Fri, 30 Apr 2021 11:16:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=gWgou43N/REI3vCWovvIFRFe1+3L9BtJuzs8qkI4ZTc=; b=ailMLbDZGd+sJje0ND+2+t0LXkby5OkW8Lc6ClmcDV2Ds88XRpigvL5jiNke3Uyond 2R8HedHBSTuOaoxPU+YjI9AKRRQltil75OIsWNfYQbkXYn66y9VPIT44FoGu60Lgavst vBaR35BILgcn4k+hG9ZcFSS1ImmaZe1ycUSkTR8oMF/NMPoRK9oAkl/WoYNf+dfvYtIT GrnEkKGpoZeP/BoXjgZt0+STdgp5eGb0kiqmDIpN4U/mKmpTX0gmROpES6XRbM4hWAzX tH2mkVzyx2OnJgqWNv9tGjDjYJiZUsQiS9pxblXigDjOFO7guh82E8w40s+lG6ITPar1 PL7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=gWgou43N/REI3vCWovvIFRFe1+3L9BtJuzs8qkI4ZTc=; b=Kpo5Vw5WumMS7wfvMwStysoMGZPzUsXBDwxqq1HM5boDAC+IQi+UD+ySZPYFtrOrdM ELhRakUfU5jMC+ipeuT3+EzON1DB+WXV0P1r6qUfT84Sa2dZm42FYQ+JslaxuBww9Nf9 h3lKOmhm/29uL/nepgN6+qMvLVi6qBF8avmD1oAd58t60uk+R25Hnqx7v0cZ8tcwppbi bWjvd6EhGnLEHabKcISC/9eLVVtX18mUzJH1pWQWyx8FTZ3AH+9pKdcYBtVuFdsAgo91 RZ5pDofC+FnODbw6OjUHc1va4ttsuXzUIiKUC2BHciPrG3jMZ8ntyMIW3Cg7TX1M4W+j 9Q5g== X-Gm-Message-State: AOAM531gbnutDUWT4IfCKf4+pTfNyoox3uYoKckJdTJVachmAiYXZTRM UWErs04D3KOWXN9jec1O0YZN2eiSCdcqEBF7 X-Google-Smtp-Source: ABdhPJx27g8WyJBH+3mJ17htb/uR8GvVii3tiHB+NJtJH2F4OhF4MvRh5x7wwBwni7gP/3JxlhktTA== X-Received: by 2002:a63:e206:: with SMTP id q6mr5671196pgh.225.1619806590793; Fri, 30 Apr 2021 11:16:30 -0700 (PDT) Received: from localhost ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id g16sm3005839pfu.45.2021.04.30.11.16.29 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 30 Apr 2021 11:16:30 -0700 (PDT) From: Xin Long To: network dev , linux-sctp@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, Marcelo Ricardo Leitner , jere.leppanen@nokia.com, Alexander Sverdlin Subject: [PATCH net 3/3] sctp: do asoc update earlier in sctp_sf_do_dupcook_b Date: Sat, 1 May 2021 02:15:57 +0800 Message-Id: X-Mailer: git-send-email 2.1.0 In-Reply-To: <8a5afb3b24785e8837332dbec388ddf4f40c2297.1619806333.git.lucien.xin@gmail.com> References: <8a5afb3b24785e8837332dbec388ddf4f40c2297.1619806333.git.lucien.xin@gmail.com> In-Reply-To: References: Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The same thing should be done for sctp_sf_do_dupcook_b(). Meanwhile, SCTP_CMD_UPDATE_ASSOC cmd can be removed. Signed-off-by: Xin Long --- include/net/sctp/command.h | 1 - net/sctp/sm_sideeffect.c | 26 ------------------------- net/sctp/sm_statefuns.c | 47 +++++++++++++++++++++++++++++----------------- 3 files changed, 30 insertions(+), 44 deletions(-) diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h index e8df72e..5e84888 100644 --- a/include/net/sctp/command.h +++ b/include/net/sctp/command.h @@ -68,7 +68,6 @@ enum sctp_verb { SCTP_CMD_ASSOC_FAILED, /* Handle association failure. */ SCTP_CMD_DISCARD_PACKET, /* Discard the whole packet. */ SCTP_CMD_GEN_SHUTDOWN, /* Generate a SHUTDOWN chunk. */ - SCTP_CMD_UPDATE_ASSOC, /* Update association information. */ SCTP_CMD_PURGE_OUTQUEUE, /* Purge all data waiting to be sent. */ SCTP_CMD_SETUP_T2, /* Hi-level, setup T2-shutdown parms. */ SCTP_CMD_RTO_PENDING, /* Set transport's rto_pending. */ diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 0948f14..ce15d59 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -826,28 +826,6 @@ static void sctp_cmd_setup_t2(struct sctp_cmd_seq *cmds, asoc->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = t->rto; } -static void sctp_cmd_assoc_update(struct sctp_cmd_seq *cmds, - struct sctp_association *asoc, - struct sctp_association *new) -{ - struct net *net = asoc->base.net; - struct sctp_chunk *abort; - - if (!sctp_assoc_update(asoc, new)) - return; - - abort = sctp_make_abort(asoc, NULL, sizeof(struct sctp_errhdr)); - if (abort) { - sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0); - sctp_add_cmd_sf(cmds, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); - } - sctp_add_cmd_sf(cmds, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNABORTED)); - sctp_add_cmd_sf(cmds, SCTP_CMD_ASSOC_FAILED, - SCTP_PERR(SCTP_ERROR_RSRC_LOW)); - SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS); - SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB); -} - /* Helper function to change the state of an association. */ static void sctp_cmd_new_state(struct sctp_cmd_seq *cmds, struct sctp_association *asoc, @@ -1301,10 +1279,6 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type, sctp_endpoint_add_asoc(ep, asoc); break; - case SCTP_CMD_UPDATE_ASSOC: - sctp_cmd_assoc_update(commands, asoc, cmd->obj.asoc); - break; - case SCTP_CMD_PURGE_OUTQUEUE: sctp_outq_teardown(&asoc->outqueue); break; diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index e8ccc4e..d0b6036 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -1773,6 +1773,30 @@ enum sctp_disposition sctp_sf_do_5_2_3_initack( return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands); } +static int sctp_sf_do_assoc_update(struct sctp_association *asoc, + struct sctp_association *new, + struct sctp_cmd_seq *cmds) +{ + struct net *net = asoc->base.net; + struct sctp_chunk *abort; + + if (!sctp_assoc_update(asoc, new)) + return -ENOMEM; + + abort = sctp_make_abort(asoc, NULL, sizeof(struct sctp_errhdr)); + if (abort) { + sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0); + sctp_add_cmd_sf(cmds, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); + } + sctp_add_cmd_sf(cmds, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNABORTED)); + sctp_add_cmd_sf(cmds, SCTP_CMD_ASSOC_FAILED, + SCTP_PERR(SCTP_ERROR_RSRC_LOW)); + SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS); + SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB); + + return 0; +} + /* Unexpected COOKIE-ECHO handler for peer restart (Table 2, action 'A') * * Section 5.2.4 @@ -1853,21 +1877,8 @@ static enum sctp_disposition sctp_sf_do_dupcook_a( sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_ASCONF_QUEUE, SCTP_NULL()); /* Update the content of current association. */ - if (sctp_assoc_update((struct sctp_association *)asoc, new_asoc)) { - struct sctp_chunk *abort; - - abort = sctp_make_abort(asoc, NULL, sizeof(struct sctp_errhdr)); - if (abort) { - sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0); - sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); - } - sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNABORTED)); - sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, - SCTP_PERR(SCTP_ERROR_RSRC_LOW)); - SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS); - SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB); + if (sctp_sf_do_assoc_update((struct sctp_association *)asoc, new_asoc, commands)) goto nomem; - } repl = sctp_make_cookie_ack(asoc, chunk); if (!repl) @@ -1940,14 +1951,16 @@ static enum sctp_disposition sctp_sf_do_dupcook_b( if (!sctp_auth_chunk_verify(net, chunk, new_asoc)) return SCTP_DISPOSITION_DISCARD; - /* Update the content of current association. */ - sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc)); sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, SCTP_STATE(SCTP_STATE_ESTABLISHED)); SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB); sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); - repl = sctp_make_cookie_ack(new_asoc, chunk); + /* Update the content of current association. */ + if (sctp_sf_do_assoc_update((struct sctp_association *)asoc, new_asoc, commands)) + goto nomem; + + repl = sctp_make_cookie_ack(asoc, chunk); if (!repl) goto nomem;