Received: by 2002:ab2:60d1:0:b0:1f7:5705:b850 with SMTP id i17csp486374lqm; Wed, 1 May 2024 06:56:59 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCUPVic6/Mx5fOoImbCbnxKMFLp20ES3dp3hdiFh4OBc6Y3eiGXXibJK4NspWAIj5LFZorQCJBqk91G7+ylDTBg6kXBKZH2s1ou0NiSXfg== X-Google-Smtp-Source: AGHT+IEL1MwY3J8FUJnJUuCtV6VqmZ8Te8B3aaJ82hP8jRVfaiYfP/MyeiVz/mXQA9msRaa/4EeR X-Received: by 2002:a17:902:d344:b0:1e7:e0a8:e5de with SMTP id l4-20020a170902d34400b001e7e0a8e5demr2401196plk.50.1714571818765; Wed, 01 May 2024 06:56:58 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1714571818; cv=pass; d=google.com; s=arc-20160816; b=ZvLxi7VMupUmzQ4n3ty9qGqrDC+rYfa1YqAV6WSifpsNFD1yIwY52zVnW8c1+UbGZt lSZtl3A0ojhmPcCyRi4ken+67vVEATNGFJKw/HwyoCXm7NHduSJpov6rhz0z9KjcL+9H iZoNYaXpO5nt2XwjLnJPT+jh3BXHa7EaOp7Vpoqibq1EJjGZ1WnDD/AgxY/K4DYThuQJ szwhhQHvVwxVyWT5PRkXfeR2gbkbjz79AZP6mUpL+zsj1NqIhqSFxj+GACSKjzi8EqkF aFG1cg+3UofhW6aJ2ZoxUr/XI+Eo9YR2E2QkdGTcxmPlF+96vwVLymW3K2c1oE8b2e7b 0nEw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:list-unsubscribe:list-subscribe :list-id:precedence:dkim-signature; bh=L5o9h7CyRbSM2Z9iwT1O8fzqhTixZGuq1fIXQDnNM8w=; fh=UsWPkzhI/QrQHCuYMnSC4BRF/oWblSpZmAIpoXhXOXM=; b=gcZFei/fEEXdV99l2NqqBzUh7a3raq0SxD4lAN9/txnMGcqGef8ZczvxGXHCXx22lp 2WgQtQOERkFA4CZ1Cr1pM0uU7Sc1G1fd5uwvYNhoMVMNv5ORzmJ/RxkYCm0LSjs0AXWw oZskmC/9a9zmX1QL/6/hfU+S99rk0U8NFe3UqGMmh9uN8VAukW8CnAV3RX4UeejKTMKW w0Rpd/bZZGOxECz/U0TtlFjzhuJL4PhugSoXsqcFedu+UYiLZnSZK10vhF13yuMX7n39 ZVCOkZhZWusn8PkiSGvyMP9OR2lC+Zs41Wrlv5NpSYKGNGYb5YL6XFHThQ65JOKv+Q8T ZfpQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=l3IRu0op; arc=pass (i=1 spf=pass spfdomain=gmail.com dkim=pass dkdomain=gmail.com dmarc=pass fromdomain=gmail.com); spf=pass (google.com: domain of linux-bluetooth+bounces-4230-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-bluetooth+bounces-4230-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id u6-20020a17090341c600b001eb0800e90asi10517519ple.249.2024.05.01.06.56.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 May 2024 06:56:58 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-bluetooth+bounces-4230-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=l3IRu0op; arc=pass (i=1 spf=pass spfdomain=gmail.com dkim=pass dkdomain=gmail.com dmarc=pass fromdomain=gmail.com); spf=pass (google.com: domain of linux-bluetooth+bounces-4230-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-bluetooth+bounces-4230-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 334E7282D24 for ; Wed, 1 May 2024 13:56:58 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 059C212EBE1; Wed, 1 May 2024 13:56:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="l3IRu0op" X-Original-To: linux-bluetooth@vger.kernel.org Received: from mail-lj1-f176.google.com (mail-lj1-f176.google.com [209.85.208.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9DF3412DDB0; Wed, 1 May 2024 13:56:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.176 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714571809; cv=none; b=q29/LmCoyoCkDV0yyC+Zf3wBH1VTOOCXlvzlWKp4dQ00dKAZQ9ewDuS7Gl0eU4A5sxxmI1FEmDnQ9sTeF+P5PRtAgwRBxBKd0QiQPlOmNvPpjHxWFRkMs8CrO6tMwxqNCTzLAvFcM+uTfy7+bTw5BLerE3WTYG1Tt6z+C5mwq2o= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714571809; c=relaxed/simple; bh=I9/sonkekUKP61+tVuNej9l/6SsNnlJ9LSTUd/rfZkA=; h=MIME-Version:References:In-Reply-To:From:Date:Message-ID:Subject: To:Cc:Content-Type; b=tihdZYRJ7xhvgaO+/I5VVZK7iYN0ZoUUHJ7qFsMCsO48TOuAtMHzkd4/qlUzCOy8EP3nog/u6x0FVxcaiKN8a9CcmFiNXLZVcqcz8cSYQRDp4xmip+SmoFCF6n2/BNfLbBiJ/iID9eTV0ZM8E6ubS/x9SW/o74nPkzWc4WBQZTI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=l3IRu0op; arc=none smtp.client-ip=209.85.208.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-lj1-f176.google.com with SMTP id 38308e7fff4ca-2d8a24f8a3cso84067781fa.1; Wed, 01 May 2024 06:56:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1714571806; x=1715176606; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=L5o9h7CyRbSM2Z9iwT1O8fzqhTixZGuq1fIXQDnNM8w=; b=l3IRu0opfmLIEF0/N0hfjbthorxTNwYVHI0tMcBx5t0Q4x9RBJTSWqtFf0BO+jH6gv Cdpnx1pBDNbn4M0CGMjVbVvm4OiG97oC655FB1F98wQ/mUPyjdECB9KIjUeZbEAATca2 WDCxPsEi3O+dyY3DlEe9KzHZCoIKi4UE3dyOT3CD7AoQFs9iATbLbBbuCcXkGtoR/rza kmUftA0TRD4iwiDXi2zVDSLoZ+OtjyYJr6sPODRm0sCasCdAw5bwvjOME/RkvQbTaZoe 5nhYR2/99+6BmG9kDq+SgBdM/qItlHaMNS4APbiDqaaRLB6mkkOhlLf3qepXMwmgaeHx cdFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714571806; x=1715176606; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=L5o9h7CyRbSM2Z9iwT1O8fzqhTixZGuq1fIXQDnNM8w=; b=GRNYSPA0gMY0pwFOL1zoMHdD9RN0Jn8t9AOl7VK5jh2k+joJ7eA3GyszuvMX77Q6DT 8hFoDIWl4cFg+JnPQzgKCHCm6L1EP7PrF/6s+ItUhmTTdTbfRKY176pdcRHbZsPKMEQs Tsks0ZMsul5cJava0B452tsNHSi9uQQS+bKM/ZpXlIiCbQPHf0JP5Wumk7A0ybOQMRD/ obZcQTUmMKKIV6Hw7YYGKTuJ8Ct4xv2me8uT0m/bLwSUhG8a13S37ouRZLAvJbIgitPR XuGMneDX6wQhTOzRcVqMRtprdnyKDrhWFzfJKoTvyDqOw3q0RAOa+5JCIb5vFuiY/ffz Ep5w== X-Forwarded-Encrypted: i=1; AJvYcCV/6N+DL4g15Y7Gc9/BTLFUUh6tEi/jhW/e0SlH7d6Os+ty5e5A/O7ZAY5j5HwXAnzmsRNqbqBWtqyKQ1j5VZNOU/n9a8M5Aw7jT/FvTmt7OwsHXe0jRdbNxryu1lRUXJCIZ4q8GE3Bhy35uT7sBoXw8ygqF6UXKNcJ+Y8TI2Ne2Rrc4fe7 X-Gm-Message-State: AOJu0YyfasAsYlGPmgpIVu7XfRupZou2j5kt961VBrlM6drVcVtBOE7c UGIS987tB5uAkw1poRlGt4iOt/uEiFiqJLFhSmoVZcBqTezOiVgFCBGbjWQlUmBtsfopTuDXZ21 7IwRgXEvrpu1GS/EdAESqMbTjalw= X-Received: by 2002:a05:651c:1a07:b0:2dd:c9fc:c472 with SMTP id by7-20020a05651c1a0700b002ddc9fcc472mr2102817ljb.26.1714571804965; Wed, 01 May 2024 06:56:44 -0700 (PDT) Precedence: bulk X-Mailing-List: linux-bluetooth@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 References: <20240501042936.2579739-1-iam@sung-woo.kim> In-Reply-To: <20240501042936.2579739-1-iam@sung-woo.kim> From: Luiz Augusto von Dentz Date: Wed, 1 May 2024 09:56:32 -0400 Message-ID: Subject: Re: [PATCH v2] Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init() To: Sungwoo Kim Cc: daveti@purdue.edu, benquike@gmail.com, Marcel Holtmann , Johan Hedberg , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-bluetooth@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Sungwoo, On Wed, May 1, 2024 at 12:32=E2=80=AFAM Sungwoo Kim wrot= e: > > Hi Luiz, could you review this patch? > > This patch prevents a div-by-zero error and potential int overflow by > adding a range check for MTU in hci_cc_le_read_buffer_size() and > hci_cc_le_read_buffer_size_v2(). > Also, hci_connect_le() will refuse to allocate hcon if the MTU is not in > the valid range. > > Bug description: > > l2cap_le_flowctl_init() can cause both div-by-zero and an integer overflo= w. > > l2cap_le_flowctl_init() > chan->mps =3D min_t(u16, chan->imtu, chan->conn->mtu - L2CAP_HDR_SIZE); > chan->rx_credits =3D (chan->imtu / chan->mps) + 1; <- div-by-zero > > Here, chan->conn->mtu could be less than or equal to L2CAP_HDR_SIZE (4). > If mtu is 4, it causes div-by-zero. If mtu is less than 4, it causes an > integer overflow. > > How mtu could have such low value: > > hci_cc_le_read_buffer_size() > hdev->le_mtu =3D __le16_to_cpu(rp->le_mtu); > > l2cap_conn_add() > conn->mtu =3D hcon->hdev->le_mtu; > > As shown, mtu is an input from an HCI device. So, any HCI device can > set mtu value to any value, such as lower than 4. > According to the spec v5.4 7.8.2 LE Read Buffer Size command, the value > should be fall in [0x001b, 0xffff]. > > Thank you, > Sungwoo. > > divide error: 0000 [#1] PREEMPT SMP KASAN NOPTI > CPU: 0 PID: 67 Comm: kworker/u5:0 Tainted: G W 6.9.0-rc5+= #20 > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/0= 1/2014 > Workqueue: hci0 hci_rx_work > RIP: 0010:l2cap_le_flowctl_init+0x19e/0x3f0 net/bluetooth/l2cap_core.c:54= 7 > Code: e8 17 17 0c 00 66 41 89 9f 84 00 00 00 bf 01 00 00 00 41 b8 02 00 0= 0 00 4c 89 fe 4c 89 e2 89 d9 e8 27 17 0c 00 44 89 f0 31 d2 <66> f7 f3 89 c3= ff c3 4d 8d b7 88 00 00 00 4c 89 f0 48 c1 e8 03 42 > RSP: 0018:ffff88810bc0f858 EFLAGS: 00010246 > RAX: 00000000000002a0 RBX: 0000000000000000 RCX: dffffc0000000000 > RDX: 0000000000000000 RSI: ffff88810bc0f7c0 RDI: ffffc90002dcb66f > RBP: ffff88810bc0f880 R08: aa69db2dda70ff01 R09: 0000ffaaaaaaaaaa > R10: 0084000000ffaaaa R11: 0000000000000000 R12: ffff88810d65a084 > R13: dffffc0000000000 R14: 00000000000002a0 R15: ffff88810d65a000 > FS: 0000000000000000(0000) GS:ffff88811ac00000(0000) knlGS:0000000000000= 000 > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > CR2: 0000000020000100 CR3: 0000000103268003 CR4: 0000000000770ef0 > PKRU: 55555554 > Call Trace: > > l2cap_le_connect_req net/bluetooth/l2cap_core.c:4902 [inline] > l2cap_le_sig_cmd net/bluetooth/l2cap_core.c:5420 [inline] > l2cap_le_sig_channel net/bluetooth/l2cap_core.c:5486 [inline] > l2cap_recv_frame+0xe59d/0x11710 net/bluetooth/l2cap_core.c:6809 > l2cap_recv_acldata+0x544/0x10a0 net/bluetooth/l2cap_core.c:7506 > hci_acldata_packet net/bluetooth/hci_core.c:3939 [inline] > hci_rx_work+0x5e5/0xb20 net/bluetooth/hci_core.c:4176 > process_one_work kernel/workqueue.c:3254 [inline] > process_scheduled_works+0x90f/0x1530 kernel/workqueue.c:3335 > worker_thread+0x926/0xe70 kernel/workqueue.c:3416 > kthread+0x2e3/0x380 kernel/kthread.c:388 > ret_from_fork+0x5c/0x90 arch/x86/kernel/process.c:147 > ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 > > Modules linked in: > ---[ end trace 0000000000000000 ]--- > > Signed-off-by: Sungwoo Kim > --- > v1 -> v2: > - Reply with an error code if a given MTU is not valid. > - Refuse hcon allocation if MTU is not still valid. > > include/net/bluetooth/hci.h | 6 ++++++ > net/bluetooth/hci_conn.c | 4 ++++ > net/bluetooth/hci_event.c | 6 ++++++ > 3 files changed, 16 insertions(+) > > diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h > index 5c12761cb..a7bc07e9c 100644 > --- a/include/net/bluetooth/hci.h > +++ b/include/net/bluetooth/hci.h > @@ -1666,6 +1666,12 @@ struct hci_cp_le_set_event_mask { > __u8 mask[8]; > } __packed; > > +/* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E > + * 7.8.2 LE Read Buffer Size command > + */ > +#define HCI_MIN_LE_MTU 0x001b > +#define HCI_MAX_LE_MTU 0xFFFF Don't think we really need the MAX value here since it is that same as the maximum field can assume so doing x > MAX is sort of useless as it loops around if that happens. > #define HCI_OP_LE_READ_BUFFER_SIZE 0x2002 > struct hci_rp_le_read_buffer_size { > __u8 status; > diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c > index 05346250f..0b86a7452 100644 > --- a/net/bluetooth/hci_conn.c > +++ b/net/bluetooth/hci_conn.c > @@ -1277,6 +1277,10 @@ struct hci_conn *hci_connect_le(struct hci_dev *hd= ev, bdaddr_t *dst, > return ERR_PTR(-EOPNOTSUPP); > } > > + /* Check the mtu is valid */ > + if (hdev->le_mtu < HCI_MIN_LE_MTU || HCI_MAX_LE_MTU < hdev->le_mt= u) > + return ERR_PTR(-ECONNREFUSED); > + That probably needs to be done on hci_conn_add if we want to capture both incoming and outgoing. > /* Since the controller supports only one LE connection attempt a= t a > * time, we return -EBUSY if there is any connection attempt runn= ing. > */ > diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c > index 4a27e4a17..a8563cbe2 100644 > --- a/net/bluetooth/hci_event.c > +++ b/net/bluetooth/hci_event.c > @@ -1263,6 +1263,9 @@ static u8 hci_cc_le_read_buffer_size(struct hci_dev= *hdev, void *data, > > BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts= ); > > + if (hdev->le_mtu < HCI_MIN_LE_MTU || HCI_MAX_LE_MTU < hdev->le_mt= u) > + return HCI_ERROR_INVALID_PARAMETERS; Value 0x00 means 'No dedicated LE Buffer exists. Use the HCI_Read_Buffer_Size command.' so it is not invalid to return it. > return rp->status; > } > > @@ -3821,6 +3824,9 @@ static u8 hci_cc_le_read_buffer_size_v2(struct hci_= dev *hdev, void *data, > BT_DBG("%s acl mtu %d:%d iso mtu %d:%d", hdev->name, hdev->acl_mt= u, > hdev->acl_pkts, hdev->iso_mtu, hdev->iso_pkts); > > + if (hdev->le_mtu < HCI_MIN_LE_MTU || HCI_MAX_LE_MTU < hdev->le_mt= u) > + return HCI_ERROR_INVALID_PARAMETERS; Ditto, this should really be: if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU) > return rp->status; > } > > -- > 2.34.1 > --=20 Luiz Augusto von Dentz