Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp2554413yba; Mon, 6 May 2019 07:57:17 -0700 (PDT) X-Google-Smtp-Source: APXvYqwHQYyF9KJpMcxo4cxYH1ywe9ryMXq0jzo84fDd3t6advKrB3pfI092ge3btkKmlv8UGHTG X-Received: by 2002:a62:864a:: with SMTP id x71mr34871537pfd.228.1557154637551; Mon, 06 May 2019 07:57:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1557154637; cv=none; d=google.com; s=arc-20160816; b=uScyEYFCkqzkmuMJILeDUAwqw3edtTKrut1MQvNEM/ZQbJTXualavsbXFhB1PNlxQN ctcttd1anFv7DVcvFjJdL0uj09pOwIqyyoPbZdTfRVHGpZrBUSn9Aq6ty97cnYBEqrYC vgYuuJTewrc2C/T0gI3CLLmmOvMy2j2zPudmhWm5KB0n9cBWlOXMkvr9Z3ByIjtnnTLX 9NIP/v8nYT2Xc8YJTUnBTimAEguW05XK4v2RRMAswzAJBXXgKDh9IaOqWe3yIjr9ckxo 6DIDUZHMRn1MpW1irosUhmqKg5nJqfQ5+iPu9FQoJuj3HWPsNoe7H9u6hSTOmBxHpSe4 BkiQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=IojOMDkeCk9felDeZz0YPt2OawrpHIzwD4gthtAMCRg=; b=Ashmx4R3hamXyMVcLbeWVcpk0AfdEgE9fDmPcR+Ot1GBkUsQtEUujHpSAjENYxRhbt yXOxic7s7cnnQRnFtTo1chgq8eQnGxOQDq1PI3GQgj7uqToLNt9RU3oZD0WOBKvhH/RL 5VZ1flvoUWyU+4ylNF2u3VY3xBhCUlipdZTBi9NsUO9cIkDtCEnh5+KV3E6eoioW7R8l oqq2qEG5q5qJA2d3HetuLtK0RVlgLK0C2SPUjN1CPh6zKgx1acNnus9X0Y9MXl6QmgXk SXXZrsvKIxzZSTN+UiNnTtJxDftJHoeW3BzTDLE1qAJoT/4/oNdDTQW3nMhoSWkJaBcw iijA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=nyVct5WL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r140si13579960pgr.585.2019.05.06.07.56.59; Mon, 06 May 2019 07:57:17 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=nyVct5WL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727969AbfEFOpU (ORCPT + 99 others); Mon, 6 May 2019 10:45:20 -0400 Received: from mail.kernel.org ([198.145.29.99]:42014 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728936AbfEFOpT (ORCPT ); Mon, 6 May 2019 10:45:19 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 852A720449; Mon, 6 May 2019 14:45:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1557153918; bh=I76lwri+SjSPIYCojg29PrKsuI+OD/wafhcHYOsn9fI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nyVct5WLG/CrNQRw2sfB1CPCM3+1wc8am9Dia7qTj7fM3cRIEbqOH9QkZudauIzkp 9YF5BHjNYx857Qx4KcEDak/9yBtdGSwYK5cpP8y+4Y/+J3LZpQE9mTzfAzhbBmn3al O/s3JyceElmHmyI9Q227sNbJtBgDKBG8jaFgs4qg= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ying Xu , Xin Long , Neil Horman , Marcelo Ricardo Leitner , "David S. Miller" Subject: [PATCH 4.14 05/75] sctp: avoid running the sctp state machine recursively Date: Mon, 6 May 2019 16:32:13 +0200 Message-Id: <20190506143053.733939313@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190506143053.287515952@linuxfoundation.org> References: <20190506143053.287515952@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Xin Long [ Upstream commit fbd019737d71e405f86549fd738f81e2ff3dd073 ] Ying triggered a call trace when doing an asconf testing: BUG: scheduling while atomic: swapper/12/0/0x10000100 Call Trace: [] dump_stack+0x19/0x1b [] __schedule_bug+0x64/0x72 [] __schedule+0x9ba/0xa00 [] __cond_resched+0x26/0x30 [] _cond_resched+0x3a/0x50 [] kmem_cache_alloc_node+0x38/0x200 [] __alloc_skb+0x5d/0x2d0 [] sctp_packet_transmit+0x610/0xa20 [sctp] [] sctp_outq_flush+0x2ce/0xc00 [sctp] [] sctp_outq_uncork+0x1c/0x20 [sctp] [] sctp_cmd_interpreter.isra.22+0xc8/0x1460 [sctp] [] sctp_do_sm+0xe1/0x350 [sctp] [] sctp_primitive_ASCONF+0x3d/0x50 [sctp] [] sctp_cmd_interpreter.isra.22+0x114/0x1460 [sctp] [] sctp_do_sm+0xe1/0x350 [sctp] [] sctp_assoc_bh_rcv+0xf4/0x1b0 [sctp] [] sctp_inq_push+0x51/0x70 [sctp] [] sctp_rcv+0xa8b/0xbd0 [sctp] As it shows, the first sctp_do_sm() running under atomic context (NET_RX softirq) invoked sctp_primitive_ASCONF() that uses GFP_KERNEL flag later, and this flag is supposed to be used in non-atomic context only. Besides, sctp_do_sm() was called recursively, which is not expected. Vlad tried to fix this recursive call in Commit c0786693404c ("sctp: Fix oops when sending queued ASCONF chunks") by introducing a new command SCTP_CMD_SEND_NEXT_ASCONF. But it didn't work as this command is still used in the first sctp_do_sm() call, and sctp_primitive_ASCONF() will be called in this command again. To avoid calling sctp_do_sm() recursively, we send the next queued ASCONF not by sctp_primitive_ASCONF(), but by sctp_sf_do_prm_asconf() in the 1st sctp_do_sm() directly. Reported-by: Ying Xu Signed-off-by: Xin Long Acked-by: Neil Horman Acked-by: Marcelo Ricardo Leitner Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- include/net/sctp/command.h | 1 - net/sctp/sm_sideeffect.c | 29 ----------------------------- net/sctp/sm_statefuns.c | 35 +++++++++++++++++++++++++++-------- 3 files changed, 27 insertions(+), 38 deletions(-) --- a/include/net/sctp/command.h +++ b/include/net/sctp/command.h @@ -104,7 +104,6 @@ enum sctp_verb { SCTP_CMD_T1_RETRAN, /* Mark for retransmission after T1 timeout */ SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ SCTP_CMD_SEND_MSG, /* Send the whole use message */ - SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */ SCTP_CMD_PURGE_ASCONF_QUEUE, /* Purge all asconf queues.*/ SCTP_CMD_SET_ASOC, /* Restore association context */ SCTP_CMD_LAST --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -1092,32 +1092,6 @@ static void sctp_cmd_send_msg(struct sct } -/* Sent the next ASCONF packet currently stored in the association. - * This happens after the ASCONF_ACK was succeffully processed. - */ -static void sctp_cmd_send_asconf(struct sctp_association *asoc) -{ - struct net *net = sock_net(asoc->base.sk); - - /* Send the next asconf chunk from the addip chunk - * queue. - */ - if (!list_empty(&asoc->addip_chunk_list)) { - struct list_head *entry = asoc->addip_chunk_list.next; - struct sctp_chunk *asconf = list_entry(entry, - struct sctp_chunk, list); - list_del_init(entry); - - /* Hold the chunk until an ASCONF_ACK is received. */ - sctp_chunk_hold(asconf); - if (sctp_primitive_ASCONF(net, asoc, asconf)) - sctp_chunk_free(asconf); - else - asoc->addip_last_asconf = asconf; - } -} - - /* These three macros allow us to pull the debugging code out of the * main flow of sctp_do_sm() to keep attention focused on the real * functionality there. @@ -1763,9 +1737,6 @@ static int sctp_cmd_interpreter(enum sct } sctp_cmd_send_msg(asoc, cmd->obj.msg, gfp); break; - case SCTP_CMD_SEND_NEXT_ASCONF: - sctp_cmd_send_asconf(asoc); - break; case SCTP_CMD_PURGE_ASCONF_QUEUE: sctp_asconf_queue_teardown(asoc); break; --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -3756,6 +3756,29 @@ enum sctp_disposition sctp_sf_do_asconf( return SCTP_DISPOSITION_CONSUME; } +static enum sctp_disposition sctp_send_next_asconf( + struct net *net, + const struct sctp_endpoint *ep, + struct sctp_association *asoc, + const union sctp_subtype type, + struct sctp_cmd_seq *commands) +{ + struct sctp_chunk *asconf; + struct list_head *entry; + + if (list_empty(&asoc->addip_chunk_list)) + return SCTP_DISPOSITION_CONSUME; + + entry = asoc->addip_chunk_list.next; + asconf = list_entry(entry, struct sctp_chunk, list); + + list_del_init(entry); + sctp_chunk_hold(asconf); + asoc->addip_last_asconf = asconf; + + return sctp_sf_do_prm_asconf(net, ep, asoc, type, asconf, commands); +} + /* * ADDIP Section 4.3 General rules for address manipulation * When building TLV parameters for the ASCONF Chunk that will add or @@ -3847,14 +3870,10 @@ enum sctp_disposition sctp_sf_do_asconf_ SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); if (!sctp_process_asconf_ack((struct sctp_association *)asoc, - asconf_ack)) { - /* Successfully processed ASCONF_ACK. We can - * release the next asconf if we have one. - */ - sctp_add_cmd_sf(commands, SCTP_CMD_SEND_NEXT_ASCONF, - SCTP_NULL()); - return SCTP_DISPOSITION_CONSUME; - } + asconf_ack)) + return sctp_send_next_asconf(net, ep, + (struct sctp_association *)asoc, + type, commands); abort = sctp_make_abort(asoc, asconf_ack, sizeof(struct sctp_errhdr));