Received: by 2002:a6b:fb09:0:0:0:0:0 with SMTP id h9csp587012iog; Mon, 13 Jun 2022 08:38:58 -0700 (PDT) X-Google-Smtp-Source: ABdhPJymCcIolzdYsbD8/lUo+uxbzjPog3IzlHbuleXl9mQu+wdOVbkdOIjyhTEtJFsoGhxaXNft X-Received: by 2002:a17:906:77d1:b0:713:cc5e:e908 with SMTP id m17-20020a17090677d100b00713cc5ee908mr415416ejn.254.1655134738126; Mon, 13 Jun 2022 08:38:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1655134738; cv=none; d=google.com; s=arc-20160816; b=XbiW0oHQ3AVK5OVmcMYaZxcBEbISwjhsLL+5PCHqUV3Ftpzm+E0q1pXX6eSyUBYOb1 fNdTn+tJO+5XutkfJHDbDfGGB3GehDgjQ2onHsR8wzdq2uCwi4P0VooPZDCfrFUsig4y qHC24MyNcO25/H+HQBRyTNoME45UQ9KQGNgoviKmu08gu3agLyO6rZWgJIT/v24XSRAJ 8mdXgxVx1B36jj92wq4lPrPEPNuBdeHCs08P0k7mx5+ipoykdmdETAAdQvS2Bd3d1LYM +vYN7limNuh+Wt8YLbXnKg6v1q1GeVK0/wzBopMgTeLuxjkQ9+NI576jWSCW3JtDUkSk AZiQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=e1WxJVPourVurRxBQ87KTpeAFatE10kKH2YBeS4eV1k=; b=h0833YLIaLnuVLdjRboy5y0X8qangY49RSKQaTHJ1p+T1XAHXwpCrUsKm8bQl6JO4J balDDScE5w/L3gUE6uKNQO6YgY6GB27q0o/FX9dQrfpVW9vl7DcehkuxxfuxUXui4ZLW gtmv1JUav/YOhBWWBuyX2eOf3L5xG6jQlXJQ7TLH/6pj0mOSk5j0wXbveelTH2YfMkJx TT9ENyKhS1ZN9NdWAxH1Ha6sN0B8pGaV7R6rZq+qGB6pYhnmV0jSkTDDDjZekU3KAnNM mY9mDWCeQTLa+o0IqiS1GMdTE6VvLPBNZxCdfvclyZAjffE7qKJPLv4/SIHvOC/bLWEX 41mg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=KFwEbYiz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id a5-20020a509e85000000b0042aaec01a46si8444239edf.462.2022.06.13.08.38.33; Mon, 13 Jun 2022 08:38:58 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=KFwEbYiz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1358027AbiFML7J (ORCPT + 99 others); Mon, 13 Jun 2022 07:59:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55944 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1356828AbiFMLvg (ORCPT ); Mon, 13 Jun 2022 07:51:36 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B79621FA4B; Mon, 13 Jun 2022 03:55:19 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 4BD8EB80E93; Mon, 13 Jun 2022 10:55:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A3E80C3411F; Mon, 13 Jun 2022 10:55:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1655117717; bh=aXte8M8+iYvi07up9RCIu1tMb50yWvKB6aiELdMdwpc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KFwEbYizj7XCqy+U+1Q5vmkypdJHCBLdgrPonVkurUs+DL5Snj8Rt1DHJJhSdamen uNVLlsQX/hXHC4owKKVeGqEDcGl6BKFFZhBAOVMVG1FBdRREKX7TOdYaeYm5AA6XQy PxSwtaSWOa7SkKMxGL3RtjIBGZFbFoR1YnpZ6GgU= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Duoming Zhou , Krzysztof Kozlowski , Jakub Kicinski , Sasha Levin Subject: [PATCH 4.19 106/287] NFC: hci: fix sleep in atomic context bugs in nfc_hci_hcp_message_tx Date: Mon, 13 Jun 2022 12:08:50 +0200 Message-Id: <20220613094927.092178832@linuxfoundation.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220613094923.832156175@linuxfoundation.org> References: <20220613094923.832156175@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-8.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Duoming Zhou [ Upstream commit b413b0cb008646e9f24ce5253cb3cf7ee217aff6 ] There are sleep in atomic context bugs when the request to secure element of st21nfca is timeout. The root cause is that kzalloc and alloc_skb with GFP_KERNEL parameter and mutex_lock are called in st21nfca_se_wt_timeout which is a timer handler. The call tree shows the execution paths that could lead to bugs: (Interrupt context) st21nfca_se_wt_timeout nfc_hci_send_event nfc_hci_hcp_message_tx kzalloc(..., GFP_KERNEL) //may sleep alloc_skb(..., GFP_KERNEL) //may sleep mutex_lock() //may sleep This patch moves the operations that may sleep into a work item. The work item will run in another kernel thread which is in process context to execute the bottom half of the interrupt. So it could prevent atomic context from sleeping. Fixes: 2130fb97fecf ("NFC: st21nfca: Adding support for secure element") Signed-off-by: Duoming Zhou Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220518115733.62111-1-duoming@zju.edu.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/nfc/st21nfca/se.c | 17 ++++++++++++++--- drivers/nfc/st21nfca/st21nfca.h | 1 + 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/nfc/st21nfca/se.c b/drivers/nfc/st21nfca/se.c index ced3c20d6453..f69d2ed5a3e2 100644 --- a/drivers/nfc/st21nfca/se.c +++ b/drivers/nfc/st21nfca/se.c @@ -252,7 +252,7 @@ int st21nfca_hci_se_io(struct nfc_hci_dev *hdev, u32 se_idx, } EXPORT_SYMBOL(st21nfca_hci_se_io); -static void st21nfca_se_wt_timeout(struct timer_list *t) +static void st21nfca_se_wt_work(struct work_struct *work) { /* * No answer from the secure element @@ -265,8 +265,9 @@ static void st21nfca_se_wt_timeout(struct timer_list *t) */ /* hardware reset managed through VCC_UICC_OUT power supply */ u8 param = 0x01; - struct st21nfca_hci_info *info = from_timer(info, t, - se_info.bwi_timer); + struct st21nfca_hci_info *info = container_of(work, + struct st21nfca_hci_info, + se_info.timeout_work); pr_debug("\n"); @@ -284,6 +285,13 @@ static void st21nfca_se_wt_timeout(struct timer_list *t) info->se_info.cb(info->se_info.cb_context, NULL, 0, -ETIME); } +static void st21nfca_se_wt_timeout(struct timer_list *t) +{ + struct st21nfca_hci_info *info = from_timer(info, t, se_info.bwi_timer); + + schedule_work(&info->se_info.timeout_work); +} + static void st21nfca_se_activation_timeout(struct timer_list *t) { struct st21nfca_hci_info *info = from_timer(info, t, @@ -376,6 +384,7 @@ int st21nfca_apdu_reader_event_received(struct nfc_hci_dev *hdev, switch (event) { case ST21NFCA_EVT_TRANSMIT_DATA: del_timer_sync(&info->se_info.bwi_timer); + cancel_work_sync(&info->se_info.timeout_work); info->se_info.bwi_active = false; r = nfc_hci_send_event(hdev, ST21NFCA_DEVICE_MGNT_GATE, ST21NFCA_EVT_SE_END_OF_APDU_TRANSFER, NULL, 0); @@ -405,6 +414,7 @@ void st21nfca_se_init(struct nfc_hci_dev *hdev) struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); init_completion(&info->se_info.req_completion); + INIT_WORK(&info->se_info.timeout_work, st21nfca_se_wt_work); /* initialize timers */ timer_setup(&info->se_info.bwi_timer, st21nfca_se_wt_timeout, 0); info->se_info.bwi_active = false; @@ -432,6 +442,7 @@ void st21nfca_se_deinit(struct nfc_hci_dev *hdev) if (info->se_info.se_active) del_timer_sync(&info->se_info.se_active_timer); + cancel_work_sync(&info->se_info.timeout_work); info->se_info.bwi_active = false; info->se_info.se_active = false; } diff --git a/drivers/nfc/st21nfca/st21nfca.h b/drivers/nfc/st21nfca/st21nfca.h index 94ffb0501e87..7e2923ac9263 100644 --- a/drivers/nfc/st21nfca/st21nfca.h +++ b/drivers/nfc/st21nfca/st21nfca.h @@ -152,6 +152,7 @@ struct st21nfca_se_info { se_io_cb_t cb; void *cb_context; + struct work_struct timeout_work; }; struct st21nfca_hci_info { -- 2.35.1