Received: by 2002:a05:6a10:c604:0:0:0:0 with SMTP id y4csp2826973pxt; Mon, 9 Aug 2021 09:47:08 -0700 (PDT) X-Google-Smtp-Source: ABdhPJymAYrnM7OQd+N37odsquDrgaiFURToMAuWl5fgsHUbZ8r7xmcVepkLZXSB7vq9Z3R7bUnN X-Received: by 2002:a17:906:3a02:: with SMTP id z2mr8651907eje.1.1628527628632; Mon, 09 Aug 2021 09:47:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1628527628; cv=none; d=google.com; s=arc-20160816; b=HZzr42h0BaWKkYsgoxxHZP1+3qEmvhEd93KX7ZfhbdmLwbxGzt9r5YgtiWXEengJDh rMfNzppRgqN9WUkmdVK/pKiCtSngCoZ5yYCU+zaT14yAuvIjwFtIXqcqY3Rmk3NQunln gFeyv63SjytRqTYiSrD/9MadsFG3feGWgWF7uIWgucbuMUbNE+bpiunXzaVKPlCXUkJ1 iVk4tvNQARQgiNKevAFrqwbjfH+ljH5X0xn3O2v3aD2aSv0ZLJ4DD0ShSBXHj0qt6IjB 1WeJwBNQHNgPVnQw9LVOyDQtolHsQsfsk54KtUmhHXlkA/v0IObCPhKi792OMSR/Twgt YZtA== 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=4UD967RcjbxyD35Ue9BbSVa+PVHU86PK1T77CUN9OWc=; b=q1CWvDi1j7jMJq+8qFfWeAH8d+JRms7srwuwkgvVtES6dMDrSWAbI9eSxkJOdx0oTn N0KofD21K+4eHuZrSpMJQXgO6thWC6JVi2KzY9T/XNyk3/lZnqamW2rHV2gErsfSvbrT J1PwDktGKxphxThCrL6Fini4hYhiov1baYc9GkbrgV+wpICu+bQQRglaHFEyps3k++gu WTLVB2gBH5gs5OoCqW0pyTwqupRN029s53XLTC5f9nGrMnTE6COjRbWVnLgAcsg5D0ZN AkeaLHUsR3ODuemCOHD3pgZCpEBSpsunZVdiVvlzY5j+5BUc5p8G0TG/SH768lta0BwZ KsEg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=siw2kCOO; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bi5si17893011ejb.664.2021.08.09.09.46.14; Mon, 09 Aug 2021 09:47:08 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=siw2kCOO; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233175AbhHIQms (ORCPT + 99 others); Mon, 9 Aug 2021 12:42:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47516 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229456AbhHIQmr (ORCPT ); Mon, 9 Aug 2021 12:42:47 -0400 Received: from mail-yb1-xb33.google.com (mail-yb1-xb33.google.com [IPv6:2607:f8b0:4864:20::b33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9804FC0613D3; Mon, 9 Aug 2021 09:42:26 -0700 (PDT) Received: by mail-yb1-xb33.google.com with SMTP id a201so30639433ybg.12; Mon, 09 Aug 2021 09:42:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=4UD967RcjbxyD35Ue9BbSVa+PVHU86PK1T77CUN9OWc=; b=siw2kCOOntvOHok2OZvJ3cP0wQ5FUaNTsZZ0JdXNIrcGUjPO7ZZgojwSA/mfGlqFZ/ esYG89m+I6+mXKXM7Wvp+tOResfzbCDWRN0tja1qv0dwunAJ+Wgp1oqoH/X2Srjm/2io 2D5RRHIcBk9UolXuAZxFpCbeZ7S90c2ljg9nqgP650XQTHeP2bTmWYsNRNgB9ftzfYk4 g5RUBIp4RgtyLtDkGm+Zz8rxpyFfKASu2jLrNEjovg5lqgBH0UM7N4CyeroLeUQo/uCM 9tPpNiLErY0kLBs85AV9QBJCxQ6hR9GEWkqylS58+By4dwBobamWrcPyJANZhOQiyTrF p7qw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=4UD967RcjbxyD35Ue9BbSVa+PVHU86PK1T77CUN9OWc=; b=C2cWSqLiuBClTq87HlUAjVDZZIsnnsSSHK4xLcK272sWakUB16dYYbO5i0hIaeJNjw UlEZOW6ufOmMFefZvWAemKHU0x+gLOhd4AaGKGGpvMQoVdkpEPR2HY5F+oY1oRnsJ8jJ LgFwdFSmI1ym0byB/Bh6BZiw3bBLLfU4XGufDUT/9sK1VUUqqIINsLLFyP+S2FPQRKv5 +8jtaaTBN08+jam1naWXzKHp35SSKBlJvc+K+wM61FQCjbs6UZw15dV3omvCob9EGaiD UXIJOC7pCUAJ9iiG8CSnCyxfI9ggps7zI6KcRhMi/UvXhlVtS91uUgHmedXx8Y+sfsIh B8ww== X-Gm-Message-State: AOAM5336Z08aMjSyOQ9pYOlqmdywQ4XIoHhX/vbowEKigJ/QB8DgBId5 x1NS6jEUMSRDvE/1I8oQlUa4B3VDV14ktjuQOoc= X-Received: by 2002:a25:9b03:: with SMTP id y3mr30133017ybn.264.1628527345735; Mon, 09 Aug 2021 09:42:25 -0700 (PDT) MIME-Version: 1.0 References: <20210804154712.929986-1-desmondcheongzx@gmail.com> <20210804154712.929986-2-desmondcheongzx@gmail.com> <0fc64ddd-45f0-667f-b8cb-bd958280586f@gmail.com> In-Reply-To: <0fc64ddd-45f0-667f-b8cb-bd958280586f@gmail.com> From: Luiz Augusto von Dentz Date: Mon, 9 Aug 2021 09:42:14 -0700 Message-ID: Subject: Re: [RESEND PATCH v5 1/6] Bluetooth: schedule SCO timeouts with delayed_work To: Desmond Cheong Zhi Xi Cc: Marcel Holtmann , Johan Hedberg , David Miller , Jakub Kicinski , sudipm.mukherjee@gmail.com, "linux-bluetooth@vger.kernel.org" , "open list:NETWORKING [GENERAL]" , Linux Kernel Mailing List , skhan@linuxfoundation.org, Greg Kroah-Hartman , linux-kernel-mentees@lists.linuxfoundation.org, syzbot+2f6d7c28bb4bf7e82060@syzkaller.appspotmail.com Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Hi Desmond, On Sun, Aug 8, 2021 at 9:04 PM Desmond Cheong Zhi Xi wrote: > > On 6/8/21 3:06 am, Luiz Augusto von Dentz wrote: > > Hi Desmond, > > > > On Wed, Aug 4, 2021 at 8:48 AM Desmond Cheong Zhi Xi > > wrote: > >> > >> struct sock.sk_timer should be used as a sock cleanup timer. However, > >> SCO uses it to implement sock timeouts. > >> > >> This causes issues because struct sock.sk_timer's callback is run in > >> an IRQ context, and the timer callback function sco_sock_timeout takes > >> a spin lock on the socket. However, other functions such as > >> sco_conn_del and sco_conn_ready take the spin lock with interrupts > >> enabled. > >> > >> This inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} lock usage could > >> lead to deadlocks as reported by Syzbot [1]: > >> CPU0 > >> ---- > >> lock(slock-AF_BLUETOOTH-BTPROTO_SCO); > >> > >> lock(slock-AF_BLUETOOTH-BTPROTO_SCO); > >> > >> To fix this, we use delayed work to implement SCO sock timouts > >> instead. This allows us to avoid taking the spin lock on the socket in > >> an IRQ context, and corrects the misuse of struct sock.sk_timer. > >> > >> As a note, cancel_delayed_work is used instead of > >> cancel_delayed_work_sync in sco_sock_set_timer and > >> sco_sock_clear_timer to avoid a deadlock. In the future, the call to > >> bh_lock_sock inside sco_sock_timeout should be changed to lock_sock to > >> synchronize with other functions using lock_sock. However, since > >> sco_sock_set_timer and sco_sock_clear_timer are sometimes called under > >> the locked socket (in sco_connect and __sco_sock_close), > >> cancel_delayed_work_sync might cause them to sleep until an > >> sco_sock_timeout that has started finishes running. But > >> sco_sock_timeout would also sleep until it can grab the lock_sock. > >> > >> Using cancel_delayed_work is fine because sco_sock_timeout does not > >> change from run to run, hence there is no functional difference > >> between: > >> 1. waiting for a timeout to finish running before scheduling another > >> timeout > >> 2. scheduling another timeout while a timeout is running. > >> > >> Link: https://syzkaller.appspot.com/bug?id=9089d89de0502e120f234ca0fc8a703f7368b31e [1] > >> Reported-by: syzbot+2f6d7c28bb4bf7e82060@syzkaller.appspotmail.com > >> Tested-by: syzbot+2f6d7c28bb4bf7e82060@syzkaller.appspotmail.com > >> Signed-off-by: Desmond Cheong Zhi Xi > >> --- > >> net/bluetooth/sco.c | 41 +++++++++++++++++++++++++++++++++++------ > >> 1 file changed, 35 insertions(+), 6 deletions(-) > >> > >> diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c > >> index ffa2a77a3e4c..89cb987ca9eb 100644 > >> --- a/net/bluetooth/sco.c > >> +++ b/net/bluetooth/sco.c > >> @@ -48,6 +48,8 @@ struct sco_conn { > >> spinlock_t lock; > >> struct sock *sk; > >> > >> + struct delayed_work timeout_work; > >> + > >> unsigned int mtu; > >> }; > >> > >> @@ -74,9 +76,20 @@ struct sco_pinfo { > >> #define SCO_CONN_TIMEOUT (HZ * 40) > >> #define SCO_DISCONN_TIMEOUT (HZ * 2) > >> > >> -static void sco_sock_timeout(struct timer_list *t) > >> +static void sco_sock_timeout(struct work_struct *work) > >> { > >> - struct sock *sk = from_timer(sk, t, sk_timer); > >> + struct sco_conn *conn = container_of(work, struct sco_conn, > >> + timeout_work.work); > >> + struct sock *sk; > >> + > >> + sco_conn_lock(conn); > >> + sk = conn->sk; > >> + if (sk) > >> + sock_hold(sk); > >> + sco_conn_unlock(conn); > >> + > >> + if (!sk) > >> + return; > >> > >> BT_DBG("sock %p state %d", sk, sk->sk_state); > >> > >> @@ -91,14 +104,27 @@ static void sco_sock_timeout(struct timer_list *t) > >> > >> static void sco_sock_set_timer(struct sock *sk, long timeout) > >> { > >> + struct delayed_work *work; > > > > Minor nitpick but I don't think using a dedicated variable here makes > > much sense. > > > > Thanks for the feedback, Luiz. Agreed, I can make the change in the next > version of the series after the other patches are reviewed. Others look good, so please go ahead and send the new version once you address these comments. > Best wishes, > Desmond > > >> + if (!sco_pi(sk)->conn) > >> + return; > >> + work = &sco_pi(sk)->conn->timeout_work; > >> + > >> BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout); > >> - sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); > >> + cancel_delayed_work(work); > >> + schedule_delayed_work(work, timeout); > >> } > >> > >> static void sco_sock_clear_timer(struct sock *sk) > >> { > >> + struct delayed_work *work; > > > > Ditto. > > > >> + if (!sco_pi(sk)->conn) > >> + return; > >> + work = &sco_pi(sk)->conn->timeout_work; > >> + > >> BT_DBG("sock %p state %d", sk, sk->sk_state); > >> - sk_stop_timer(sk, &sk->sk_timer); > >> + cancel_delayed_work(work); > >> } > >> > >> /* ---- SCO connections ---- */ > >> @@ -179,6 +205,9 @@ static void sco_conn_del(struct hci_conn *hcon, int err) > >> bh_unlock_sock(sk); > >> sco_sock_kill(sk); > >> sock_put(sk); > >> + > >> + /* Ensure no more work items will run before freeing conn. */ > >> + cancel_delayed_work_sync(&conn->timeout_work); > >> } > >> > >> hcon->sco_data = NULL; > >> @@ -193,6 +222,8 @@ static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, > >> sco_pi(sk)->conn = conn; > >> conn->sk = sk; > >> > >> + INIT_DELAYED_WORK(&conn->timeout_work, sco_sock_timeout); > >> + > >> if (parent) > >> bt_accept_enqueue(parent, sk, true); > >> } > >> @@ -500,8 +531,6 @@ static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, > >> > >> sco_pi(sk)->setting = BT_VOICE_CVSD_16BIT; > >> > >> - timer_setup(&sk->sk_timer, sco_sock_timeout, 0); > >> - > >> bt_sock_link(&sco_sk_list, sk); > >> return sk; > >> } > >> -- > >> 2.25.1 > >> > > > > > -- Luiz Augusto von Dentz