Received: by 2002:a6b:fb09:0:0:0:0:0 with SMTP id h9csp3027814iog; Mon, 27 Jun 2022 07:45:41 -0700 (PDT) X-Google-Smtp-Source: AGRyM1s1/8AGhsFzfLT9Aq1rseoVBpU8KimolPb5w2jLKxBkxM3lIrmoibBtGt46Umvp6VySE7tM X-Received: by 2002:aa7:cb01:0:b0:437:8a8a:dbb3 with SMTP id s1-20020aa7cb01000000b004378a8adbb3mr8657963edt.74.1656341141088; Mon, 27 Jun 2022 07:45:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656341141; cv=none; d=google.com; s=arc-20160816; b=oaCokVJBHM1f36vloHZah+/k+TdDwuFuJe/s0hU4xBQtvpmkWHsVGbj7BKa85a5+PN du5yLkHb6UuA6lDsnmjNoE3at/41i7hTc/r7w6C3bmUi2KZrUObAaART0T8/EAFxpXUI tx0XRd9O5s3tNDHMxBozOuFkYbehuAnfE5ZQQFFqaQjP/HA9bezm8ZF93A6uU7uL1rzM bAUfSgoXQVbf92svcLYYClsK04gJOaZdHXBEa8j5/OrStXdeWzicNDAqrQ/jhxlWCiHQ aWeSgmHw6FR3odHXxO3AXu4/N4CUlok0t24Xkx6OIg3WtzzWY4mKoN1bff0ZM3ae+FxM Sm+g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=1hHJnJQFjFuIToWQDKaqG2N15/HHTzVxPaO06uGF804=; b=E7RsJf23zm7pOpfpB0M4EUaO9pelsJqeQvu4i//w5aiQb3l4RKEk7vefPMmZopo7H6 08dRKt+428H+O2+goOkLG85O+ds56VeqMeC7ypuXudEqbB+ZQVxqlB+1Zk7YYrpwaAUW 7Ew2tMHe7pjirU9+PvKfXY57jfDAL286p0aFy9AYDkiUfa//NDFVIWDoWOrbEMB35h9X pBbmQbeSiDCOtGXnE6kw8lndZEVO9+nrz9Hn0rqcG4J8Kxdnl6lYDvzyWtKiBxhlxfTs Q4fe5lSNfVp6VelvgNnaq5FXnpfOOnq+sRzPyj9zPwoKP1vb3n4aGp4A4gEaZxaYjm// Vlwg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=qTM2lIpY; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id w3-20020a056402268300b0042e30989df3si15404552edd.147.2022.06.27.07.44.41; Mon, 27 Jun 2022 07:45:41 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-bluetooth-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=@google.com header.s=20210112 header.b=qTM2lIpY; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236180AbiF0Olh (ORCPT + 99 others); Mon, 27 Jun 2022 10:41:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55130 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235067AbiF0Olg (ORCPT ); Mon, 27 Jun 2022 10:41:36 -0400 Received: from mail-yw1-x1129.google.com (mail-yw1-x1129.google.com [IPv6:2607:f8b0:4864:20::1129]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AD6A3BE3F for ; Mon, 27 Jun 2022 07:41:35 -0700 (PDT) Received: by mail-yw1-x1129.google.com with SMTP id 00721157ae682-3178ea840easo87302887b3.13 for ; Mon, 27 Jun 2022 07:41:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=1hHJnJQFjFuIToWQDKaqG2N15/HHTzVxPaO06uGF804=; b=qTM2lIpYwNuYEZQHZ/Ga8EB8z8R7o9AlA+eFAqPxYsUT4s9V9gs4aimap7TPAFPAaA ELUH0DHsK9PT8ELf2dOUQ4WQNMbFH3LZpKgMsvmF3l8l+QU2g6NII4dNHODvqI+AP2Db E4bZLJ5qn6m5BvtP3b80w2chOfqLRLwTFHL5OgSvy1ylgaAqrQdZVeb8rfTXkGffV5qD 0CR3PXBpHQfC3kB3Qw7CeYcUGVvSGHmsCuOnH3tXUnt4opHjvfidbEXTZvnww+jzze0N mY8whBGPhmS8XmcFL98LqcG4CuVlwXAdfqY3s6h5MpWMqN+EUi4/duM3XUjkfqNGpvGi DYbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=1hHJnJQFjFuIToWQDKaqG2N15/HHTzVxPaO06uGF804=; b=XfVG/+lretltcQpjjuefW94/hPAHcGXYdq9Q+865XXbsbtDaIs7+7+kTeYJ+bDv/oI CsmuQ7hph4K+rhpvk23LUJACR/mFGBMH/ukXqLixNfjPRZ0j46Iy+GRcjoPPs4uZYkbm PM/G6SDm8ckSxOr7+zTF2b3TSjeLuTMRwdQBF/M9mrVFhtGSVks2hrTtlXE3jzo25w9V MfIVFblOyQgqDP7AQtPkUnt3FSQ1Lb0royGVTE4ycZXrcleIe/hSbIa+REV4PihjeQDJ McMAey8k21ibwjD6QZa98Zi5izT3IDHtqSrKqDmeb4AGC6z9QwWOtmwDGD1/W0k+0Wsf bv3A== X-Gm-Message-State: AJIora+CGxtzGu8swj02jjbQPDfngfSWUOH1LLXOPRSjnIb7/34CaVgW /g+a/jZo/qmy8ed0uSglqnDCLi4nTF4ZDQ1xkOIPaA== X-Received: by 2002:a81:9b93:0:b0:317:8c9d:4c22 with SMTP id s141-20020a819b93000000b003178c9d4c22mr14864512ywg.278.1656340894677; Mon, 27 Jun 2022 07:41:34 -0700 (PDT) MIME-Version: 1.0 References: <20220622082716.478486-1-lee.jones@linaro.org> In-Reply-To: <20220622082716.478486-1-lee.jones@linaro.org> From: Eric Dumazet Date: Mon, 27 Jun 2022 16:41:23 +0200 Message-ID: Subject: Re: [RESEND 1/1] Bluetooth: Use chan_list_lock to protect the whole put/destroy invokation To: Lee Jones Cc: LKML , stable@kernel.org, Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , "David S. Miller" , Jakub Kicinski , Paolo Abeni , linux-bluetooth@vger.kernel.org, netdev Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-17.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, ENV_AND_HDR_SPF_MATCH,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL,USER_IN_DEF_SPF_WL 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-bluetooth@vger.kernel.org On Wed, Jun 22, 2022 at 10:27 AM Lee Jones wrote: > > This change prevents a use-after-free caused by one of the worker > threads starting up (see below) *after* the final channel reference > has been put() during sock_close() but *before* the references to the > channel have been destroyed. > > refcount_t: increment on 0; use-after-free. > BUG: KASAN: use-after-free in refcount_dec_and_test+0x20/0xd0 > Read of size 4 at addr ffffffc114f5bf18 by task kworker/u17:14/705 > > CPU: 4 PID: 705 Comm: kworker/u17:14 Tainted: G S W 4.14.234-00003-g1fb6d0bd49a4-dirty #28 > Hardware name: Qualcomm Technologies, Inc. SM8150 V2 PM8150 Google Inc. MSM sm8150 Flame DVT (DT) > Workqueue: hci0 hci_rx_work > Call trace: > dump_backtrace+0x0/0x378 > show_stack+0x20/0x2c > dump_stack+0x124/0x148 > print_address_description+0x80/0x2e8 > __kasan_report+0x168/0x188 > kasan_report+0x10/0x18 > __asan_load4+0x84/0x8c > refcount_dec_and_test+0x20/0xd0 > l2cap_chan_put+0x48/0x12c > l2cap_recv_frame+0x4770/0x6550 > l2cap_recv_acldata+0x44c/0x7a4 > hci_acldata_packet+0x100/0x188 > hci_rx_work+0x178/0x23c > process_one_work+0x35c/0x95c > worker_thread+0x4cc/0x960 > kthread+0x1a8/0x1c4 > ret_from_fork+0x10/0x18 > > Cc: stable@kernel.org When was the bug added ? (Fixes: tag please) > Cc: Marcel Holtmann > Cc: Johan Hedberg > Cc: Luiz Augusto von Dentz > Cc: "David S. Miller" > Cc: Eric Dumazet > Cc: Jakub Kicinski > Cc: Paolo Abeni > Cc: linux-bluetooth@vger.kernel.org > Cc: netdev@vger.kernel.org > Signed-off-by: Lee Jones > --- > net/bluetooth/l2cap_core.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c > index ae78490ecd3d4..82279c5919fd8 100644 > --- a/net/bluetooth/l2cap_core.c > +++ b/net/bluetooth/l2cap_core.c > @@ -483,9 +483,7 @@ static void l2cap_chan_destroy(struct kref *kref) > > BT_DBG("chan %p", chan); > > - write_lock(&chan_list_lock); > list_del(&chan->global_l); > - write_unlock(&chan_list_lock); > > kfree(chan); > } > @@ -501,7 +499,9 @@ void l2cap_chan_put(struct l2cap_chan *c) > { > BT_DBG("chan %p orig refcnt %u", c, kref_read(&c->kref)); > > + write_lock(&chan_list_lock); > kref_put(&c->kref, l2cap_chan_destroy); > + write_unlock(&chan_list_lock); > } > EXPORT_SYMBOL_GPL(l2cap_chan_put); > > -- > 2.36.1.255.ge46751e96f-goog > I do not think this patch is correct. a kref does not need to be protected by a write lock. This might shuffle things enough to work around a particular repro you have. If the patch was correct why not protect kref_get() sides ? Before the &hdev->rx_work is scheduled (queue_work(hdev->workqueue, &hdev->rx_work), a reference must be taken. Then this reference must be released at the end of hci_rx_work() or when hdev->workqueue is canceled. This refcount is not needed _if_ the workqueue is properly canceled at device dismantle, in a synchronous way. I do not see this hdev->rx_work being canceled, maybe this is the real issue. There is a call to drain_workqueue() but this is not enough I think, because hci_recv_frame() can re-arm queue_work(hdev->workqueue, &hdev->rx_work);