From patchwork Sat Dec 3 17:48:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cengiz Can X-Patchwork-Id: 1711723 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=e9yGrG+H; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NPckx28ghz23yd for ; Sun, 4 Dec 2022 04:49:27 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1p1WdZ-0007Io-LY; Sat, 03 Dec 2022 17:49:17 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1p1WdW-0007Ho-9d for kernel-team@lists.ubuntu.com; Sat, 03 Dec 2022 17:49:14 +0000 Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id D8AC83F1E9 for ; Sat, 3 Dec 2022 17:49:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1670089751; bh=67eaZjb/I08CaMy1LtTV0EmQqk3vBVYwquCoO4D5qBU=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=e9yGrG+HR2uwCqvUd8htv+Uq5CbqC/WWr69w53Ocmx5b/ax5RGyWr2qq9OHXEldCA uM9juPAdpnsOUQ40e1EzBAxuVl1gMNMNv3ccJn7AhDjsvLwxqMXbkNui9Vnhcw9pRI lUcyzcpti6wljKy3bySho7UEuMwg2fWCD87C2P1b97R1VbASou/4S/LOp7I2SbTH90 jZTW7KZyeMWRf86nHmocKZvnyJVqfMBrP8OYJRwfpiyz3UmRy8GvcOhlgpSib4Tc1N W4YEOO2ctLjiuKuEA7Ukwzx/dUgAFHYnywRV4Zwexizfd4h7UjZ6R2Vjf50gSSESgi IR30s80eZ7vcg== Received: by mail-wm1-f72.google.com with SMTP id o5-20020a05600c510500b003cfca1a327fso4221385wms.8 for ; Sat, 03 Dec 2022 09:49:11 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=67eaZjb/I08CaMy1LtTV0EmQqk3vBVYwquCoO4D5qBU=; b=H2FV9M7PkOX1xYg5/bbUEwv6eR8OywQUtE7oRr9Q+mdBKg0G/lp++eAZAnylY+jOIw wLAViUtCDIu6hdMzOoBIumyIePQMUmTOg0kkotlES4YfnQDI4Pg0D8/bx/6R//WgWYn2 pwxUfjFYIgtdQZF7mRy6RRI8qwbUIn4Mn03PDEVIcCnP2B9jouNhxhR6orZ+kTMsFliU XcXTE1xfXKFj5Zv2CSLFkfx4pfKCsm7pVei2dTSkRAE0VgcEcU0Mp6Ww42v+ghDys++r 2UFQqV/QIb2YAcigzL11+Dn/cUNsbcy/i2zC6Rrx35aPatDZ6qYulcifo8oIfFoM5bCs b3ww== X-Gm-Message-State: ANoB5pmfwLNPfEQgkt02k5mYcOY/HpRE6ZPKY3IAAP1tW/t5u3Y+c3jX Bp0j1IsPFtO7XPzLyhwWONNjeMNXhxfLI9tc1R0gjcukSPT0synyrX5TbejWQKWnyWPSGp7I3IB tjXFRJJv+4zd92u+pPmdeAqveowupoGHk5bsMGjtA6w== X-Received: by 2002:adf:f6c3:0:b0:241:ffd4:d128 with SMTP id y3-20020adff6c3000000b00241ffd4d128mr27226079wrp.234.1670089750913; Sat, 03 Dec 2022 09:49:10 -0800 (PST) X-Google-Smtp-Source: AA0mqf5075EFRFHQOzcrkKn5VwdS4ccZAKvUbp3M1O8ME6iQ/gVo3aUoJfKRfLkgOFF7rsTtgBxZMg== X-Received: by 2002:adf:f6c3:0:b0:241:ffd4:d128 with SMTP id y3-20020adff6c3000000b00241ffd4d128mr27226075wrp.234.1670089750617; Sat, 03 Dec 2022 09:49:10 -0800 (PST) Received: from localhost ([92.44.145.54]) by smtp.gmail.com with ESMTPSA id m14-20020a5d624e000000b00241dd5de644sm9772505wrv.97.2022.12.03.09.49.10 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 03 Dec 2022 09:49:10 -0800 (PST) From: Cengiz Can To: kernel-team@lists.ubuntu.com Subject: [SRU Bionic v2 1/8] Bluetooth: L2CAP: Derive MPS from connection MTU Date: Sat, 3 Dec 2022 20:48:36 +0300 Message-Id: <20221203174842.543278-2-cengiz.can@canonical.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221203174842.543278-1-cengiz.can@canonical.com> References: <20221203174842.543278-1-cengiz.can@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Luiz Augusto von Dentz This ensures the MPS can fit in a single HCI fragment so each segment don't have to be reassembled at HCI level, in addition to that also remove the debugfs entry to configure the MPS. Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Marcel Holtmann CVE-2022-42896 (cherry picked from commit fe1493101ac1313cbdbef1af65342fb17d944e71) Signed-off-by: Cengiz Can --- include/net/bluetooth/l2cap.h | 1 - net/bluetooth/l2cap_core.c | 14 +++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index da0ef935c5a9..7ddd50a19529 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -456,7 +456,6 @@ struct l2cap_conn_param_update_rsp { #define L2CAP_CONN_PARAM_REJECTED 0x0001 #define L2CAP_LE_MAX_CREDITS 10 -#define L2CAP_LE_DEFAULT_MPS 230 struct l2cap_le_conn_req { __le16 psm; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 35c04727ddc0..5ae66a5ff642 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -52,7 +52,6 @@ static LIST_HEAD(chan_list); static DEFINE_RWLOCK(chan_list_lock); static u16 le_max_credits = L2CAP_LE_MAX_CREDITS; -static u16 le_default_mps = L2CAP_LE_DEFAULT_MPS; static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, u8 ident, u16 dlen, void *data); @@ -556,7 +555,8 @@ static void l2cap_le_flowctl_init(struct l2cap_chan *chan) chan->sdu_len = 0; chan->tx_credits = 0; chan->rx_credits = le_max_credits; - chan->mps = min_t(u16, chan->imtu, le_default_mps); + /* Derive MPS from connection MTU to stop HCI fragmentation */ + chan->mps = min_t(u16, chan->imtu, chan->conn->mtu - L2CAP_HDR_SIZE); skb_queue_head_init(&chan->tx_q); } @@ -1318,6 +1318,8 @@ static void l2cap_le_connect(struct l2cap_chan *chan) if (test_and_set_bit(FLAG_LE_CONN_REQ_SENT, &chan->flags)) return; + l2cap_le_flowctl_init(chan); + req.psm = chan->psm; req.scid = cpu_to_le16(chan->scid); req.mtu = cpu_to_le16(chan->imtu); @@ -5591,8 +5593,6 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn, goto response_unlock; } - l2cap_le_flowctl_init(chan); - bacpy(&chan->src, &conn->hcon->src); bacpy(&chan->dst, &conn->hcon->dst); chan->src_type = bdaddr_src_type(conn->hcon); @@ -5604,6 +5604,9 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn, chan->tx_credits = __le16_to_cpu(req->credits); __l2cap_chan_add(conn, chan); + + l2cap_le_flowctl_init(chan); + dcid = chan->scid; credits = chan->rx_credits; @@ -7247,7 +7250,6 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, case L2CAP_MODE_BASIC: break; case L2CAP_MODE_LE_FLOWCTL: - l2cap_le_flowctl_init(chan); break; case L2CAP_MODE_ERTM: case L2CAP_MODE_STREAMING: @@ -7792,8 +7794,6 @@ int __init l2cap_init(void) debugfs_create_u16("l2cap_le_max_credits", 0644, bt_debugfs, &le_max_credits); - debugfs_create_u16("l2cap_le_default_mps", 0644, bt_debugfs, - &le_default_mps); return 0; } From patchwork Sat Dec 3 17:48:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cengiz Can X-Patchwork-Id: 1711725 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=MlCKf6Es; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NPckx23D1z23np for ; Sun, 4 Dec 2022 04:49:27 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1p1WdY-0007IG-FG; Sat, 03 Dec 2022 17:49:16 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1p1WdV-0007Hg-NH for kernel-team@lists.ubuntu.com; Sat, 03 Dec 2022 17:49:13 +0000 Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 8C1BF3F1C3 for ; Sat, 3 Dec 2022 17:49:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1670089753; bh=62Y+xkNbdTozb6qtmLScpOrNZ6V5vhGR6I2C+2cQSvE=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=MlCKf6EseF9EgkBtsOCoOI0Zwq2BFwJAvfaUeVkU+QBolzEnZ3eKXEF4ESap5pmDg vWQyoB6q96XdQ9uESSsdSJnSVdRfjIQNQvuClCRtjqy0tS3IyYcLzRGwPEeo2btHjm YG99RWgPCgnyZN6YQxEwdY7p6HT9AcOS9oIyCkUqoGL4tf98+uejtLCaEIYSdI5OBV CUkPPpmrKeRt1VVq4uZ4hI7Ho1gKN0l45MD506OnDLgunpvn0ufdBYitr5Ic9V4kfO YABeaNoicGPlu84Vu36Aad5FVTlP9OrCgDCJ0VLIZW4i3VBsg+IwCKZuMyqZioAmcI 7ADuvgb2eKE8g== Received: by mail-wm1-f71.google.com with SMTP id h4-20020a1c2104000000b003d01b66fe65so5843118wmh.2 for ; Sat, 03 Dec 2022 09:49:13 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=62Y+xkNbdTozb6qtmLScpOrNZ6V5vhGR6I2C+2cQSvE=; b=551eHVzyuBHPKWexUI/UCiGRX+MEN2BLzy9MYcXAKaS8k2jXbm6lBL9ISYV65f62YY bPzJB6Zp0LJCL28PoGCyaCRSbiYUXDF1lTLApr3N1URpy2EqrLG0t6b5TxPtY8ccdkE0 ec1vHd2CyCreZ948hwGVV7AvC9MeeWnpraSY0YrV2EFYeJs5m1hiVv/+MIBRBeiJlAis //yY3Zk1qi4qOGy7FwtHvWKN7vFGVB/WBo7ugm+8jdpcbi5u7qsxoF04zOVyYG3lSlmf b02H8GKWn3JzAu92MBMmiwT78TfkFcXR/tLEUFiCm6NiruhMCIyG21CyI93CI5Y44wWG 9LDA== X-Gm-Message-State: ANoB5pmEpuY5hNqMlDASiDDo21nBPF4V1fEMsmjOgGkh6JTO6GPQsEAI mkWwmLitgMZBryTbUyfUK3HBjx9xmZcZds/cLgtxfVCJF6W+Sbtfqs3PWWsFiJ6C1HC+Ydev4KB abgkNm7/xwaAxKjr7UZFqT/9N0upiugU0ENNSOyXQ5w== X-Received: by 2002:a5d:4601:0:b0:241:bf7b:b2e5 with SMTP id t1-20020a5d4601000000b00241bf7bb2e5mr43326108wrq.626.1670089752945; Sat, 03 Dec 2022 09:49:12 -0800 (PST) X-Google-Smtp-Source: AA0mqf5D6GU9tgN1HxXpwbUC67Tom/whM79d2ftKoG73b1o3nl3fNSx11x8OEnlTNDZoLdk6MQ6pZQ== X-Received: by 2002:a5d:4601:0:b0:241:bf7b:b2e5 with SMTP id t1-20020a5d4601000000b00241bf7bb2e5mr43326100wrq.626.1670089752644; Sat, 03 Dec 2022 09:49:12 -0800 (PST) Received: from localhost ([92.44.145.54]) by smtp.gmail.com with ESMTPSA id v15-20020a5d6b0f000000b002421ed1d8c8sm9825610wrw.103.2022.12.03.09.49.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 03 Dec 2022 09:49:12 -0800 (PST) From: Cengiz Can To: kernel-team@lists.ubuntu.com Subject: [SRU Bionic v2 2/8] Bluetooth: L2CAP: Derive rx credits from MTU and MPS Date: Sat, 3 Dec 2022 20:48:37 +0300 Message-Id: <20221203174842.543278-3-cengiz.can@canonical.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221203174842.543278-1-cengiz.can@canonical.com> References: <20221203174842.543278-1-cengiz.can@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Luiz Augusto von Dentz Give enough rx credits for a full packet instead of using an arbitrary number which may not be enough depending on the MTU and MPS which can cause interruptions while waiting for more credits, also remove debugfs entry for l2cap_le_max_credits. With these changes the credits are restored after each SDU is received instead of using fixed threshold, this way it is garanteed that there will always be enough credits to send a packet without waiting more credits to arrive. Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Marcel Holtmann CVE-2022-42896 (cherry picked from commit 96cd8eaa131f0ffd4cfae09e1b4bdfafb9570907) Signed-off-by: Cengiz Can --- include/net/bluetooth/l2cap.h | 2 -- net/bluetooth/l2cap_core.c | 42 ++++++++++++++++++++++------------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 7ddd50a19529..6e9216d81939 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -455,8 +455,6 @@ struct l2cap_conn_param_update_rsp { #define L2CAP_CONN_PARAM_ACCEPTED 0x0000 #define L2CAP_CONN_PARAM_REJECTED 0x0001 -#define L2CAP_LE_MAX_CREDITS 10 - struct l2cap_le_conn_req { __le16 psm; __le16 scid; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 5ae66a5ff642..55fe255d5af4 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -51,8 +51,6 @@ static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD; static LIST_HEAD(chan_list); static DEFINE_RWLOCK(chan_list_lock); -static u16 le_max_credits = L2CAP_LE_MAX_CREDITS; - static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, u8 ident, u16 dlen, void *data); static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, @@ -554,9 +552,10 @@ static void l2cap_le_flowctl_init(struct l2cap_chan *chan) chan->sdu_last_frag = NULL; chan->sdu_len = 0; chan->tx_credits = 0; - chan->rx_credits = le_max_credits; /* Derive MPS from connection MTU to stop HCI fragmentation */ chan->mps = min_t(u16, chan->imtu, chan->conn->mtu - L2CAP_HDR_SIZE); + /* Give enough credits for a full packet */ + chan->rx_credits = (chan->imtu / chan->mps) + 1; skb_queue_head_init(&chan->tx_q); } @@ -6836,13 +6835,10 @@ static void l2cap_chan_le_send_credits(struct l2cap_chan *chan) struct l2cap_le_credits pkt; u16 return_credits; - /* We return more credits to the sender only after the amount of - * credits falls below half of the initial amount. - */ - if (chan->rx_credits >= (le_max_credits + 1) / 2) - return; + return_credits = ((chan->imtu / chan->mps) + 1) - chan->rx_credits; - return_credits = le_max_credits - chan->rx_credits; + if (!return_credits) + return; BT_DBG("chan %p returning %u credits to sender", chan, return_credits); @@ -6856,6 +6852,21 @@ static void l2cap_chan_le_send_credits(struct l2cap_chan *chan) l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt); } +static int l2cap_le_recv(struct l2cap_chan *chan, struct sk_buff *skb) +{ + int err; + + BT_DBG("SDU reassemble complete: chan %p skb->len %u", chan, skb->len); + + /* Wait recv to confirm reception before updating the credits */ + err = chan->ops->recv(chan, skb); + + /* Update credits whenever an SDU is received */ + l2cap_chan_le_send_credits(chan); + + return err; +} + static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) { int err; @@ -6874,7 +6885,11 @@ static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) chan->rx_credits--; BT_DBG("rx_credits %u -> %u", chan->rx_credits + 1, chan->rx_credits); - l2cap_chan_le_send_credits(chan); + /* Update if remote had run out of credits, this should only happens + * if the remote is not using the entire MPS. + */ + if (!chan->rx_credits) + l2cap_chan_le_send_credits(chan); err = 0; @@ -6900,7 +6915,7 @@ static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) } if (skb->len == sdu_len) - return chan->ops->recv(chan, skb); + return l2cap_le_recv(chan, skb); chan->sdu = skb; chan->sdu_len = sdu_len; @@ -6932,7 +6947,7 @@ static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) skb = NULL; if (chan->sdu->len == chan->sdu_len) { - err = chan->ops->recv(chan, chan->sdu); + err = l2cap_le_recv(chan, chan->sdu); if (!err) { chan->sdu = NULL; chan->sdu_last_frag = NULL; @@ -7792,9 +7807,6 @@ int __init l2cap_init(void) l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs, NULL, &l2cap_debugfs_fops); - debugfs_create_u16("l2cap_le_max_credits", 0644, bt_debugfs, - &le_max_credits); - return 0; } From patchwork Sat Dec 3 17:48:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cengiz Can X-Patchwork-Id: 1711726 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=HIaq87Ms; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NPckz19pzz23yd for ; Sun, 4 Dec 2022 04:49:31 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1p1Wdd-0007M5-TK; Sat, 03 Dec 2022 17:49:22 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1p1WdY-0007I6-0z for kernel-team@lists.ubuntu.com; Sat, 03 Dec 2022 17:49:16 +0000 Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id DD1443F1C3 for ; Sat, 3 Dec 2022 17:49:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1670089755; bh=QLI1YTF0CQ8KR/I3UH/mV5nhoX1kydr922rxeDb9Cx4=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=HIaq87MsWBMhTJINtwuFL8YSF7QrsDVDugXZTeXOzgB++OKD7pRYBTxZXklpFU6ku RvB0HyAIMeCTtxGF5jYRvAUVdcGO/CHBrukhg2EV7Cib1x+AmtpphUyFBwP7w47SmH vvPr22FBrtz9YmAjOltZceFlEW8wMkpOgFeYwRj+vP9+PYhZ4aFhndXm58l8LfKE3m 7YxevTvZTtWd0mvtGcMKQkBV/pdFrySf6I3AFrPtulqPCqwv1mfm9vWzA2XEFARbuR QN63Iae674XhIb6Ro+Sg39beV1eql8oxfaCgExzLvfI4aWaNpbctzogfItHP8yE/Vz YXZPO0nXhPISQ== Received: by mail-wm1-f70.google.com with SMTP id m17-20020a05600c3b1100b003cf9cc47da5so4218084wms.9 for ; Sat, 03 Dec 2022 09:49:15 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QLI1YTF0CQ8KR/I3UH/mV5nhoX1kydr922rxeDb9Cx4=; b=l9o90N11N9WxUtyqbc5OBemSc+xU6WhZQI8el46Oi0V/vZ4jXc3E9btw8wBUd6Kj7E mi7bOIvqOXOxI3Bn3hKcfG08/kOqDihmpD9mhnaFMtnQgkp3subiCR3AYcsgKalln8K/ egcH4hEtXjm0Afq37Sk2ARMTqb1RUOwVJU/DgldHMKm8lo4mkFfESjbA4A2/X69hePb2 e0RXxgecXFOgl7wBb2VzDQ8VwuJbedoAYZefGlXeU3HU+Ev8uwokbFyJnjZa6cSk34YT w5gHduB7HlzgMTdIm4PGJXcSMQOXMNC8urpkz1bSEEMAUPjloTRcPyq1JKOPfH+8M1qW 1cXg== X-Gm-Message-State: ANoB5pkN9m61Xbm55DcNaqo03ljLIeKZqkpgKhtI2eDxaxkmsKd9yd4f 4k2L1TSOKRXLph9asYJYV+NGz8cGZrLKrOcpBwULVDLpwLl2NZaJ5vnmfwwaaa4uLW+tCnTmR3b gsvtKU58CwjaMhJT9ISUIwqjT/q/Vy9t8HHSd3ReyKA== X-Received: by 2002:adf:d0c6:0:b0:242:1873:bb28 with SMTP id z6-20020adfd0c6000000b002421873bb28mr17410652wrh.485.1670089755287; Sat, 03 Dec 2022 09:49:15 -0800 (PST) X-Google-Smtp-Source: AA0mqf6nOXjGm5VQdyIBDOgk2E4GTaDOBPCs0lVeykVilcp9DQELBfCdFalC92Su2f5pzjh77svk6w== X-Received: by 2002:adf:d0c6:0:b0:242:1873:bb28 with SMTP id z6-20020adfd0c6000000b002421873bb28mr17410633wrh.485.1670089754465; Sat, 03 Dec 2022 09:49:14 -0800 (PST) Received: from localhost ([92.44.145.54]) by smtp.gmail.com with ESMTPSA id p15-20020a5d638f000000b0024207478de3sm9755484wru.93.2022.12.03.09.49.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 03 Dec 2022 09:49:14 -0800 (PST) From: Cengiz Can To: kernel-team@lists.ubuntu.com Subject: [SRU Bionic v2 3/8] Bluetooth: Use separate L2CAP LE credit based connection result values Date: Sat, 3 Dec 2022 20:48:38 +0300 Message-Id: <20221203174842.543278-4-cengiz.can@canonical.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221203174842.543278-1-cengiz.can@canonical.com> References: <20221203174842.543278-1-cengiz.can@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Mallikarjun Phulari Add the result values specific to L2CAP LE credit based connections and change the old result values wherever they were used. Signed-off-by: Mallikarjun Phulari Signed-off-by: Marcel Holtmann CVE-2022-42896 (cherry picked from commit 571f739083e2544b343b5998608de679519de4e9) Signed-off-by: Cengiz Can --- include/net/bluetooth/l2cap.h | 17 +++++++++++------ net/bluetooth/l2cap_core.c | 26 +++++++++++++------------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 6e9216d81939..435216f24f40 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -277,12 +277,17 @@ struct l2cap_conn_rsp { #define L2CAP_CR_SEC_BLOCK 0x0003 #define L2CAP_CR_NO_MEM 0x0004 #define L2CAP_CR_BAD_AMP 0x0005 -#define L2CAP_CR_AUTHENTICATION 0x0005 -#define L2CAP_CR_AUTHORIZATION 0x0006 -#define L2CAP_CR_BAD_KEY_SIZE 0x0007 -#define L2CAP_CR_ENCRYPTION 0x0008 -#define L2CAP_CR_INVALID_SCID 0x0009 -#define L2CAP_CR_SCID_IN_USE 0x000A + +/* credit based connect results */ +#define L2CAP_CR_LE_SUCCESS 0x0000 +#define L2CAP_CR_LE_BAD_PSM 0x0002 +#define L2CAP_CR_LE_NO_MEM 0x0004 +#define L2CAP_CR_LE_AUTHENTICATION 0x0005 +#define L2CAP_CR_LE_AUTHORIZATION 0x0006 +#define L2CAP_CR_LE_BAD_KEY_SIZE 0x0007 +#define L2CAP_CR_LE_ENCRYPTION 0x0008 +#define L2CAP_CR_LE_INVALID_SCID 0x0009 +#define L2CAP_CR_LE_SCID_IN_USE 0X000A /* connect/create channel status */ #define L2CAP_CS_NO_INFO 0x0000 diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 55fe255d5af4..aed8270f6a6d 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -716,9 +716,9 @@ static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan) u16 result; if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) - result = L2CAP_CR_AUTHORIZATION; + result = L2CAP_CR_LE_AUTHORIZATION; else - result = L2CAP_CR_BAD_PSM; + result = L2CAP_CR_LE_BAD_PSM; l2cap_state_change(chan, BT_DISCONN); @@ -3743,7 +3743,7 @@ void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan) rsp.mtu = cpu_to_le16(chan->imtu); rsp.mps = cpu_to_le16(chan->mps); rsp.credits = cpu_to_le16(chan->rx_credits); - rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); + rsp.result = cpu_to_le16(L2CAP_CR_LE_SUCCESS); l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), &rsp); @@ -5378,7 +5378,7 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn, credits = __le16_to_cpu(rsp->credits); result = __le16_to_cpu(rsp->result); - if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23 || + if (result == L2CAP_CR_LE_SUCCESS && (mtu < 23 || mps < 23 || dcid < L2CAP_CID_DYN_START || dcid > L2CAP_CID_LE_DYN_END)) return -EPROTO; @@ -5399,7 +5399,7 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn, l2cap_chan_lock(chan); switch (result) { - case L2CAP_CR_SUCCESS: + case L2CAP_CR_LE_SUCCESS: if (__l2cap_get_chan_by_dcid(conn, dcid)) { err = -EBADSLT; break; @@ -5413,8 +5413,8 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn, l2cap_chan_ready(chan); break; - case L2CAP_CR_AUTHENTICATION: - case L2CAP_CR_ENCRYPTION: + case L2CAP_CR_LE_AUTHENTICATION: + case L2CAP_CR_LE_ENCRYPTION: /* If we already have MITM protection we can't do * anything. */ @@ -5557,7 +5557,7 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn, pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src, &conn->hcon->dst, LE_LINK); if (!pchan) { - result = L2CAP_CR_BAD_PSM; + result = L2CAP_CR_LE_BAD_PSM; chan = NULL; goto response; } @@ -5567,28 +5567,28 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn, if (!smp_sufficient_security(conn->hcon, pchan->sec_level, SMP_ALLOW_STK)) { - result = L2CAP_CR_AUTHENTICATION; + result = L2CAP_CR_LE_AUTHENTICATION; chan = NULL; goto response_unlock; } /* Check for valid dynamic CID range */ if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) { - result = L2CAP_CR_INVALID_SCID; + result = L2CAP_CR_LE_INVALID_SCID; chan = NULL; goto response_unlock; } /* Check if we already have channel with that dcid */ if (__l2cap_get_chan_by_dcid(conn, scid)) { - result = L2CAP_CR_SCID_IN_USE; + result = L2CAP_CR_LE_SCID_IN_USE; chan = NULL; goto response_unlock; } chan = pchan->ops->new_connection(pchan); if (!chan) { - result = L2CAP_CR_NO_MEM; + result = L2CAP_CR_LE_NO_MEM; goto response_unlock; } @@ -5624,7 +5624,7 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn, chan->ops->defer(chan); } else { l2cap_chan_ready(chan); - result = L2CAP_CR_SUCCESS; + result = L2CAP_CR_LE_SUCCESS; } response_unlock: From patchwork Sat Dec 3 17:48:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cengiz Can X-Patchwork-Id: 1711722 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=lxAvCDnQ; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NPckx2Sj4z23yf for ; Sun, 4 Dec 2022 04:49:28 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1p1Wdc-0007K2-0e; Sat, 03 Dec 2022 17:49:20 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1p1WdZ-0007J7-T8 for kernel-team@lists.ubuntu.com; Sat, 03 Dec 2022 17:49:17 +0000 Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 750423F1E9 for ; Sat, 3 Dec 2022 17:49:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1670089757; bh=9o7G3g9xiaglxPsRfg0i1vEa3el3m+sW2tXtfFyhUiY=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=lxAvCDnQofN4n47SQ4wPnDB4+XiyWn8larRpLB1z78cdf2HkPTJAs7AxIU8U/BfMv y2nLHSgaOBbfeysYXwq4uPzSePt42TBKxhqi7mnbZ/3GdCaMhdJkoRdCxq9Rcm30+4 /dhrTcsM1tya1YUJD9xF8y38/CqeGJ/UGTS9YaN7FEDz2HsaNV0a5ZXNZqE3yz93f9 k/lRdHATJIYwnatfIrn6xNJIaG0c1HpOtsSQjcuaKI8DDBi/ByC5ogDDrTglWyYv1C 1jq38es3vetSNS1wKHc8PllQ8afSxGLxnyKlj3tLwsjtAtJlYdSZbE2er3ArO+Lc79 KnJC0pjP0pr7w== Received: by mail-wm1-f72.google.com with SMTP id o5-20020a05600c510500b003cfca1a327fso4221472wms.8 for ; Sat, 03 Dec 2022 09:49:17 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9o7G3g9xiaglxPsRfg0i1vEa3el3m+sW2tXtfFyhUiY=; b=qFdNvqGM6pUa6r42aOdOY2pHkN/wmD4ucwNkIqCPyZ35nMJJX0ee1aWEH7x43H0UQB yiZPjB/8LxzM2CkeH0z0ovC68TK+wH3Hax0wP3Y+TCcpZSGgY4X44HEeE627dd+RxwyX VxYywfR7xxxFlSphXsvicauSMfNo//u+3pvfm1ML0BnTwkUO8L3cjNP5bi9PUtOwsqFM OrR/q26R2LgV47rvyvEnJR6Xb7EaexMhyYD0CpaV4k7SSMGh2+/iglUGVphMgfxIsc9X QI7LKYKtavJXZb7RqJ58gW2tAg8DIJEryPGQ5LbQso0abTHPkQrlIbPDs+uexgOn3U3B PdQQ== X-Gm-Message-State: ANoB5pl+XbyYqRtSYxo6GvfcUr+INvNr+n3MLKHpcflI+KeI9+iBUNM1 io2iNu7wuJE/xJungPp+F4/0bw6bh8i/wDxHbA5HhM/8VvZh4c37pUZHVd/9hgqXYeysx/MKb/w zSrCA0XoclIT+HWeG7SGwJxoj/bbSHx3sEGVcTGkpZQ== X-Received: by 2002:adf:f24a:0:b0:242:3be9:71c7 with SMTP id b10-20020adff24a000000b002423be971c7mr7197575wrp.329.1670089756985; Sat, 03 Dec 2022 09:49:16 -0800 (PST) X-Google-Smtp-Source: AA0mqf5uwtnGNk4FNWXNllxecK4golJJC/wrP9fyIHHpiLaZJzEirHyx+vm0tU8/n4b06SpZe0gomw== X-Received: by 2002:adf:f24a:0:b0:242:3be9:71c7 with SMTP id b10-20020adff24a000000b002423be971c7mr7197571wrp.329.1670089756771; Sat, 03 Dec 2022 09:49:16 -0800 (PST) Received: from localhost ([92.44.145.54]) by smtp.gmail.com with ESMTPSA id g8-20020a5d46c8000000b0023662d97130sm10030375wrs.20.2022.12.03.09.49.16 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 03 Dec 2022 09:49:16 -0800 (PST) From: Cengiz Can To: kernel-team@lists.ubuntu.com Subject: [SRU Bionic v2 4/8] Bluetooth: Fix not initializing L2CAP tx_credits Date: Sat, 3 Dec 2022 20:48:39 +0300 Message-Id: <20221203174842.543278-5-cengiz.can@canonical.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221203174842.543278-1-cengiz.can@canonical.com> References: <20221203174842.543278-1-cengiz.can@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Luiz Augusto von Dentz l2cap_le_flowctl_init was reseting the tx_credits which works only for outgoing connection since that set the tx_credits on the response, for incoming connections that was not the case which leaves the channel without any credits causing it to be suspended. Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Marcel Holtmann Cc: stable@vger.kernel.org # 4.20+ CVE-2022-42896 (cherry picked from commit ba8f5289f706aed94cc95b15cc5b89e22062f61f) Signed-off-by: Cengiz Can --- net/bluetooth/l2cap_core.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index aed8270f6a6d..26b220823b6b 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -546,12 +546,12 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan) } EXPORT_SYMBOL_GPL(l2cap_chan_set_defaults); -static void l2cap_le_flowctl_init(struct l2cap_chan *chan) +static void l2cap_le_flowctl_init(struct l2cap_chan *chan, u16 tx_credits) { chan->sdu = NULL; chan->sdu_last_frag = NULL; chan->sdu_len = 0; - chan->tx_credits = 0; + chan->tx_credits = tx_credits; /* Derive MPS from connection MTU to stop HCI fragmentation */ chan->mps = min_t(u16, chan->imtu, chan->conn->mtu - L2CAP_HDR_SIZE); /* Give enough credits for a full packet */ @@ -1317,7 +1317,7 @@ static void l2cap_le_connect(struct l2cap_chan *chan) if (test_and_set_bit(FLAG_LE_CONN_REQ_SENT, &chan->flags)) return; - l2cap_le_flowctl_init(chan); + l2cap_le_flowctl_init(chan, 0); req.psm = chan->psm; req.scid = cpu_to_le16(chan->scid); @@ -5600,11 +5600,10 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn, chan->dcid = scid; chan->omtu = mtu; chan->remote_mps = mps; - chan->tx_credits = __le16_to_cpu(req->credits); __l2cap_chan_add(conn, chan); - l2cap_le_flowctl_init(chan); + l2cap_le_flowctl_init(chan, __le16_to_cpu(req->credits)); dcid = chan->scid; credits = chan->rx_credits; From patchwork Sat Dec 3 17:48:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cengiz Can X-Patchwork-Id: 1711727 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=wS1FXBjU; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NPcl23BWlz23np for ; Sun, 4 Dec 2022 04:49:34 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1p1Wdg-0007Pa-Bw; Sat, 03 Dec 2022 17:49:24 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1p1Wdd-0007L7-0e for kernel-team@lists.ubuntu.com; Sat, 03 Dec 2022 17:49:21 +0000 Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id D36F93F1C3 for ; Sat, 3 Dec 2022 17:49:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1670089760; bh=SioBXg39fp78eqV3nyStcn4VgRhRjyKlwKndJco9AJA=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=wS1FXBjUzzzlH5nF77k4iDBYsp104wb4wvsgQ/RbkgWe9aQCHojXFM+e113yZbHp6 KCe3W3nhZWU4lPY8wt9QtUEgFjVWnIYHkD0kUT4+EphRJ0Xx2jPLzD5M9Cy79X84Yy zxnYxhnm+EUITpFNExvxwYmBY89//6f7aTQYcqbNCV9M8fp4X78lVnrjFV1QV+wcXP UDbGuNGedu6I723LX3StvgKAaOmtUymyxs8imZfmIAQ8wQ/heKBnYTu+37qoYXViH5 VS6kjNLjiOt23/AVnZJFp0D8+cLaOdrrRgn9p2AKwSrUBG73wZ2Ar+2WlC28ToEvt9 vj74i1ikWWowg== Received: by mail-wm1-f70.google.com with SMTP id v125-20020a1cac83000000b003cfa148576dso4228873wme.3 for ; Sat, 03 Dec 2022 09:49:20 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=SioBXg39fp78eqV3nyStcn4VgRhRjyKlwKndJco9AJA=; b=lffHEQGph9r9nWOcFd2J2rdMgkzznPF6b/VHyp2omYoxj4iKfaP55PiyMVJB8vVJyS McjJAnkLGKdnBxhDEPt21ljLDK3N4eWn1lzGrb1LSjxcx/M/C6DFzHAnQhXaAKtm2yOH 5VQfkSdz0kpXXTq4IqYG3JjY5K9Pyq2ekjOsZT1Op5aaD7/EEqXKLXHWCbZe+siBM5iD jZj2KwvVbYDwTJqiXF+HEp/sRUrdOgmy7OYR9/Ng7dgE0lNXOLfSVLTw4WwEQY+uJUb8 sAEUoluT4LCizsZq2w9aWaph7n13RsVbbH9zHcH5/vrV+K8DtXV9jvNqM8mZNmNCADL/ 7sBA== X-Gm-Message-State: ANoB5pnZBDV+0OtRFc7fIxlmcA39WoPKRUf7HKRPkII4vYzh8wUJzcTh WK7fXx9tXwcc7tKlmp9hlHZCaDyhQgzKRUS1to0U6eciR7aKN4PsCAlCAcLIuh33CkAvPz6KaSv Q8yAjEXrLT4wrPBt5JT5WJN7X/JzBj/qH86iyFpF6hQ== X-Received: by 2002:a5d:4284:0:b0:242:5057:8b23 with SMTP id k4-20020a5d4284000000b0024250578b23mr2037423wrq.51.1670089759827; Sat, 03 Dec 2022 09:49:19 -0800 (PST) X-Google-Smtp-Source: AA0mqf5jDb0+A262SKl769Hw8VUjnSaaL1STRoHEzaJ9w5yjRp6IVEiaZhIb7QcDdJWdb/Okv8ILyg== X-Received: by 2002:a5d:4284:0:b0:242:5057:8b23 with SMTP id k4-20020a5d4284000000b0024250578b23mr2037408wrq.51.1670089759342; Sat, 03 Dec 2022 09:49:19 -0800 (PST) Received: from localhost ([92.44.145.54]) by smtp.gmail.com with ESMTPSA id b16-20020a5d4b90000000b002422202fa7fsm7412616wrt.39.2022.12.03.09.49.18 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 03 Dec 2022 09:49:19 -0800 (PST) From: Cengiz Can To: kernel-team@lists.ubuntu.com Subject: [SRU Bionic v2 5/8] Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode Date: Sat, 3 Dec 2022 20:48:40 +0300 Message-Id: <20221203174842.543278-6-cengiz.can@canonical.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221203174842.543278-1-cengiz.can@canonical.com> References: <20221203174842.543278-1-cengiz.can@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Luiz Augusto von Dentz This adds the initial code for Enhanced Credit Based Mode which introduces a new socket mode called L2CAP_MODE_EXT_FLOWCTL, which for the most part work the same as L2CAP_MODE_LE_FLOWCTL but uses different PDUs to setup the connections and also works over BR/EDR. Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Marcel Holtmann CVE-2022-42896 (cherry picked from commit 15f02b91056253e8cdc592888f431da0731337b8) Signed-off-by: Cengiz Can --- include/net/bluetooth/l2cap.h | 4 + net/bluetooth/l2cap_core.c | 545 +++++++++++++++++++++++++++++++++- net/bluetooth/l2cap_sock.c | 23 +- 3 files changed, 552 insertions(+), 20 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 435216f24f40..255a30597b12 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -288,6 +288,8 @@ struct l2cap_conn_rsp { #define L2CAP_CR_LE_ENCRYPTION 0x0008 #define L2CAP_CR_LE_INVALID_SCID 0x0009 #define L2CAP_CR_LE_SCID_IN_USE 0X000A +#define L2CAP_CR_LE_UNACCEPT_PARAMS 0X000B +#define L2CAP_CR_LE_INVALID_PARAMS 0X000C /* connect/create channel status */ #define L2CAP_CS_NO_INFO 0x0000 @@ -924,6 +926,7 @@ void l2cap_cleanup_sockets(void); bool l2cap_is_socket(struct socket *sock); void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan); +void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan); void __l2cap_connect_rsp_defer(struct l2cap_chan *chan); int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm); @@ -933,6 +936,7 @@ struct l2cap_chan *l2cap_chan_create(void); void l2cap_chan_close(struct l2cap_chan *chan, int reason); int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst, u8 dst_type); +int l2cap_chan_reconfigure(struct l2cap_chan *chan, __u16 mtu); int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len); void l2cap_chan_busy(struct l2cap_chan *chan, int busy); int l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 26b220823b6b..3c0eff6e2cd1 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -560,6 +560,17 @@ static void l2cap_le_flowctl_init(struct l2cap_chan *chan, u16 tx_credits) skb_queue_head_init(&chan->tx_q); } +static void l2cap_ecred_init(struct l2cap_chan *chan, u16 tx_credits) +{ + l2cap_le_flowctl_init(chan, tx_credits); + + /* L2CAP implementations shall support a minimum MPS of 64 octets */ + if (chan->mps < L2CAP_ECRED_MIN_MPS) { + chan->mps = L2CAP_ECRED_MIN_MPS; + chan->rx_credits = (chan->imtu / chan->mps) + 1; + } +} + void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) { BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, @@ -666,6 +677,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) break; case L2CAP_MODE_LE_FLOWCTL: + case L2CAP_MODE_EXT_FLOWCTL: skb_queue_purge(&chan->tx_q); break; @@ -732,6 +744,27 @@ static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan) &rsp); } +static void l2cap_chan_ecred_connect_reject(struct l2cap_chan *chan) +{ + struct l2cap_conn *conn = chan->conn; + struct l2cap_ecred_conn_rsp rsp; + u16 result; + + if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) + result = L2CAP_CR_LE_AUTHORIZATION; + else + result = L2CAP_CR_LE_BAD_PSM; + + l2cap_state_change(chan, BT_DISCONN); + + memset(&rsp, 0, sizeof(rsp)); + + rsp.result = cpu_to_le16(result); + + l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), + &rsp); +} + static void l2cap_chan_connect_reject(struct l2cap_chan *chan) { struct l2cap_conn *conn = chan->conn; @@ -777,8 +810,16 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) { if (conn->hcon->type == ACL_LINK) l2cap_chan_connect_reject(chan); - else if (conn->hcon->type == LE_LINK) - l2cap_chan_le_connect_reject(chan); + else if (conn->hcon->type == LE_LINK) { + switch (chan->mode) { + case L2CAP_MODE_LE_FLOWCTL: + l2cap_chan_le_connect_reject(chan); + break; + case L2CAP_MODE_EXT_FLOWCTL: + l2cap_chan_ecred_connect_reject(chan); + break; + } + } } l2cap_chan_del(chan, reason); @@ -1301,8 +1342,13 @@ static void l2cap_chan_ready(struct l2cap_chan *chan) chan->conf_state = 0; __clear_chan_timer(chan); - if (chan->mode == L2CAP_MODE_LE_FLOWCTL && !chan->tx_credits) - chan->ops->suspend(chan); + switch (chan->mode) { + case L2CAP_MODE_LE_FLOWCTL: + case L2CAP_MODE_EXT_FLOWCTL: + if (!chan->tx_credits) + chan->ops->suspend(chan); + break; + } chan->state = BT_CONNECTED; @@ -1331,6 +1377,31 @@ static void l2cap_le_connect(struct l2cap_chan *chan) sizeof(req), &req); } +static void l2cap_ecred_connect(struct l2cap_chan *chan) +{ + struct l2cap_conn *conn = chan->conn; + struct { + struct l2cap_ecred_conn_req req; + __le16 scid; + } __packed pdu; + + if (test_and_set_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags)) + return; + + l2cap_ecred_init(chan, 0); + + pdu.req.psm = chan->psm; + pdu.req.mtu = cpu_to_le16(chan->imtu); + pdu.req.mps = cpu_to_le16(chan->mps); + pdu.req.credits = cpu_to_le16(chan->rx_credits); + pdu.scid = cpu_to_le16(chan->scid); + + chan->ident = l2cap_get_ident(conn); + + l2cap_send_cmd(conn, chan->ident, L2CAP_ECRED_CONN_REQ, + sizeof(pdu), &pdu); +} + static void l2cap_le_start(struct l2cap_chan *chan) { struct l2cap_conn *conn = chan->conn; @@ -1343,8 +1414,12 @@ static void l2cap_le_start(struct l2cap_chan *chan) return; } - if (chan->state == BT_CONNECT) - l2cap_le_connect(chan); + if (chan->state == BT_CONNECT) { + if (chan->mode == L2CAP_MODE_EXT_FLOWCTL) + l2cap_ecred_connect(chan); + else + l2cap_le_connect(chan); + } } static void l2cap_start_connection(struct l2cap_chan *chan) @@ -2532,6 +2607,7 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len) switch (chan->mode) { case L2CAP_MODE_LE_FLOWCTL: + case L2CAP_MODE_EXT_FLOWCTL: /* Check outgoing MTU */ if (len > chan->omtu) return -EMSGSIZE; @@ -3749,6 +3825,45 @@ void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan) &rsp); } +void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan) +{ + struct { + struct l2cap_ecred_conn_rsp rsp; + __le16 dcid[5]; + } __packed pdu; + struct l2cap_conn *conn = chan->conn; + u16 ident = chan->ident; + int i = 0; + + if (!ident) + return; + + BT_DBG("chan %p ident %d", chan, ident); + + pdu.rsp.mtu = cpu_to_le16(chan->imtu); + pdu.rsp.mps = cpu_to_le16(chan->mps); + pdu.rsp.credits = cpu_to_le16(chan->rx_credits); + pdu.rsp.result = cpu_to_le16(L2CAP_CR_LE_SUCCESS); + + mutex_lock(&conn->chan_lock); + + list_for_each_entry(chan, &conn->chan_l, list) { + if (chan->ident != ident) + continue; + + /* Reset ident so only one response is sent */ + chan->ident = 0; + + /* Include all channels pending with the same ident */ + pdu.dcid[i++] = cpu_to_le16(chan->scid); + } + + mutex_unlock(&conn->chan_lock); + + l2cap_send_cmd(conn, ident, L2CAP_ECRED_CONN_RSP, + sizeof(pdu.rsp) + i * sizeof(__le16), &pdu); +} + void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) { struct l2cap_conn_rsp rsp; @@ -5699,6 +5814,351 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn, return 0; } +static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn, + struct l2cap_cmd_hdr *cmd, u16 cmd_len, + u8 *data) +{ + struct l2cap_ecred_conn_req *req = (void *) data; + struct { + struct l2cap_ecred_conn_rsp rsp; + __le16 dcid[5]; + } __packed pdu; + struct l2cap_chan *chan, *pchan; + u16 credits, mtu, mps; + __le16 psm; + u8 result, len = 0; + int i, num_scid; + bool defer = false; + + if (cmd_len < sizeof(*req) || cmd_len - sizeof(*req) % sizeof(u16)) { + result = L2CAP_CR_LE_INVALID_PARAMS; + goto response; + } + + mtu = __le16_to_cpu(req->mtu); + mps = __le16_to_cpu(req->mps); + + if (mtu < L2CAP_ECRED_MIN_MTU || mps < L2CAP_ECRED_MIN_MPS) { + result = L2CAP_CR_LE_UNACCEPT_PARAMS; + goto response; + } + + psm = req->psm; + credits = 0; + + BT_DBG("psm 0x%2.2x mtu %u mps %u", __le16_to_cpu(psm), mtu, mps); + + memset(&pdu, 0, sizeof(pdu)); + + /* Check if we have socket listening on psm */ + pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src, + &conn->hcon->dst, LE_LINK); + if (!pchan) { + result = L2CAP_CR_LE_BAD_PSM; + goto response; + } + + mutex_lock(&conn->chan_lock); + l2cap_chan_lock(pchan); + + if (!smp_sufficient_security(conn->hcon, pchan->sec_level, + SMP_ALLOW_STK)) { + result = L2CAP_CR_LE_AUTHENTICATION; + goto unlock; + } + + result = L2CAP_CR_LE_SUCCESS; + cmd_len -= sizeof(req); + num_scid = cmd_len / sizeof(u16); + + for (i = 0; i < num_scid; i++) { + u16 scid = __le16_to_cpu(req->scid[i]); + + BT_DBG("scid[%d] 0x%4.4x", i, scid); + + pdu.dcid[i] = 0x0000; + len += sizeof(*pdu.dcid); + + /* Check for valid dynamic CID range */ + if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) { + result = L2CAP_CR_LE_INVALID_SCID; + continue; + } + + /* Check if we already have channel with that dcid */ + if (__l2cap_get_chan_by_dcid(conn, scid)) { + result = L2CAP_CR_LE_SCID_IN_USE; + continue; + } + + chan = pchan->ops->new_connection(pchan); + if (!chan) { + result = L2CAP_CR_LE_NO_MEM; + continue; + } + + bacpy(&chan->src, &conn->hcon->src); + bacpy(&chan->dst, &conn->hcon->dst); + chan->src_type = bdaddr_src_type(conn->hcon); + chan->dst_type = bdaddr_dst_type(conn->hcon); + chan->psm = psm; + chan->dcid = scid; + chan->omtu = mtu; + chan->remote_mps = mps; + + __l2cap_chan_add(conn, chan); + + l2cap_ecred_init(chan, __le16_to_cpu(req->credits)); + + /* Init response */ + if (!pdu.rsp.credits) { + pdu.rsp.mtu = cpu_to_le16(chan->imtu); + pdu.rsp.mps = cpu_to_le16(chan->mps); + pdu.rsp.credits = cpu_to_le16(chan->rx_credits); + } + + pdu.dcid[i] = cpu_to_le16(chan->scid); + + __set_chan_timer(chan, chan->ops->get_sndtimeo(chan)); + + chan->ident = cmd->ident; + + if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { + l2cap_state_change(chan, BT_CONNECT2); + defer = true; + chan->ops->defer(chan); + } else { + l2cap_chan_ready(chan); + } + } + +unlock: + l2cap_chan_unlock(pchan); + mutex_unlock(&conn->chan_lock); + l2cap_chan_put(pchan); + +response: + pdu.rsp.result = cpu_to_le16(result); + + if (defer) + return 0; + + l2cap_send_cmd(conn, cmd->ident, L2CAP_ECRED_CONN_RSP, + sizeof(pdu.rsp) + len, &pdu); + + return 0; +} + +static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn, + struct l2cap_cmd_hdr *cmd, u16 cmd_len, + u8 *data) +{ + struct l2cap_ecred_conn_rsp *rsp = (void *) data; + struct hci_conn *hcon = conn->hcon; + u16 mtu, mps, credits, result; + struct l2cap_chan *chan; + int err = 0, sec_level; + int i = 0; + + if (cmd_len < sizeof(*rsp)) + return -EPROTO; + + mtu = __le16_to_cpu(rsp->mtu); + mps = __le16_to_cpu(rsp->mps); + credits = __le16_to_cpu(rsp->credits); + result = __le16_to_cpu(rsp->result); + + BT_DBG("mtu %u mps %u credits %u result 0x%4.4x", mtu, mps, credits, + result); + + mutex_lock(&conn->chan_lock); + + cmd_len -= sizeof(*rsp); + + list_for_each_entry(chan, &conn->chan_l, list) { + u16 dcid; + + if (chan->ident != cmd->ident || + chan->mode != L2CAP_MODE_EXT_FLOWCTL || + chan->state == BT_CONNECTED) + continue; + + l2cap_chan_lock(chan); + + /* Check that there is a dcid for each pending channel */ + if (cmd_len < sizeof(dcid)) { + l2cap_chan_del(chan, ECONNREFUSED); + l2cap_chan_unlock(chan); + continue; + } + + dcid = __le16_to_cpu(rsp->dcid[i++]); + cmd_len -= sizeof(u16); + + BT_DBG("dcid[%d] 0x%4.4x", i, dcid); + + /* Check if dcid is already in use */ + if (dcid && __l2cap_get_chan_by_dcid(conn, dcid)) { + /* If a device receives a + * L2CAP_CREDIT_BASED_CONNECTION_RSP packet with an + * already-assigned Destination CID, then both the + * original channel and the new channel shall be + * immediately discarded and not used. + */ + l2cap_chan_del(chan, ECONNREFUSED); + l2cap_chan_unlock(chan); + chan = __l2cap_get_chan_by_dcid(conn, dcid); + l2cap_chan_lock(chan); + l2cap_chan_del(chan, ECONNRESET); + l2cap_chan_unlock(chan); + continue; + } + + switch (result) { + case L2CAP_CR_LE_AUTHENTICATION: + case L2CAP_CR_LE_ENCRYPTION: + /* If we already have MITM protection we can't do + * anything. + */ + if (hcon->sec_level > BT_SECURITY_MEDIUM) { + l2cap_chan_del(chan, ECONNREFUSED); + break; + } + + sec_level = hcon->sec_level + 1; + if (chan->sec_level < sec_level) + chan->sec_level = sec_level; + + /* We'll need to send a new Connect Request */ + clear_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags); + + smp_conn_security(hcon, chan->sec_level); + break; + + case L2CAP_CR_LE_BAD_PSM: + l2cap_chan_del(chan, ECONNREFUSED); + break; + + default: + /* If dcid was not set it means channels was refused */ + if (!dcid) { + l2cap_chan_del(chan, ECONNREFUSED); + break; + } + + chan->ident = 0; + chan->dcid = dcid; + chan->omtu = mtu; + chan->remote_mps = mps; + chan->tx_credits = credits; + l2cap_chan_ready(chan); + break; + } + + l2cap_chan_unlock(chan); + } + + mutex_unlock(&conn->chan_lock); + + return err; +} + +static inline int l2cap_ecred_reconf_req(struct l2cap_conn *conn, + struct l2cap_cmd_hdr *cmd, u16 cmd_len, + u8 *data) +{ + struct l2cap_ecred_reconf_req *req = (void *) data; + struct l2cap_ecred_reconf_rsp rsp; + u16 mtu, mps, result; + struct l2cap_chan *chan; + int i, num_scid; + + if (cmd_len < sizeof(*req) || cmd_len - sizeof(*req) % sizeof(u16)) { + result = L2CAP_CR_LE_INVALID_PARAMS; + goto respond; + } + + mtu = __le16_to_cpu(req->mtu); + mps = __le16_to_cpu(req->mps); + + BT_DBG("mtu %u mps %u", mtu, mps); + + if (mtu < L2CAP_ECRED_MIN_MTU) { + result = L2CAP_RECONF_INVALID_MTU; + goto respond; + } + + if (mps < L2CAP_ECRED_MIN_MPS) { + result = L2CAP_RECONF_INVALID_MPS; + goto respond; + } + + cmd_len -= sizeof(*req); + num_scid = cmd_len / sizeof(u16); + result = L2CAP_RECONF_SUCCESS; + + for (i = 0; i < num_scid; i++) { + u16 scid; + + scid = __le16_to_cpu(req->scid[i]); + if (!scid) + return -EPROTO; + + chan = __l2cap_get_chan_by_dcid(conn, scid); + if (!chan) + continue; + + /* If the MTU value is decreased for any of the included + * channels, then the receiver shall disconnect all + * included channels. + */ + if (chan->omtu > mtu) { + BT_ERR("chan %p decreased MTU %u -> %u", chan, + chan->omtu, mtu); + result = L2CAP_RECONF_INVALID_MTU; + } + + chan->omtu = mtu; + chan->remote_mps = mps; + } + +respond: + rsp.result = cpu_to_le16(result); + + l2cap_send_cmd(conn, cmd->ident, L2CAP_ECRED_RECONF_RSP, sizeof(rsp), + &rsp); + + return 0; +} + +static inline int l2cap_ecred_reconf_rsp(struct l2cap_conn *conn, + struct l2cap_cmd_hdr *cmd, u16 cmd_len, + u8 *data) +{ + struct l2cap_chan *chan; + struct l2cap_ecred_conn_rsp *rsp = (void *) data; + u16 result; + + if (cmd_len < sizeof(*rsp)) + return -EPROTO; + + result = __le16_to_cpu(rsp->result); + + BT_DBG("result 0x%4.4x", rsp->result); + + if (!result) + return 0; + + list_for_each_entry(chan, &conn->chan_l, list) { + if (chan->ident != cmd->ident) + continue; + + l2cap_chan_del(chan, ECONNRESET); + } + + return 0; +} + static inline int l2cap_le_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) @@ -5754,6 +6214,22 @@ static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn, err = l2cap_le_credits(conn, cmd, cmd_len, data); break; + case L2CAP_ECRED_CONN_REQ: + err = l2cap_ecred_conn_req(conn, cmd, cmd_len, data); + break; + + case L2CAP_ECRED_CONN_RSP: + err = l2cap_ecred_conn_rsp(conn, cmd, cmd_len, data); + break; + + case L2CAP_ECRED_RECONF_REQ: + err = l2cap_ecred_reconf_req(conn, cmd, cmd_len, data); + break; + + case L2CAP_ECRED_RECONF_RSP: + err = l2cap_ecred_reconf_rsp(conn, cmd, cmd_len, data); + break; + case L2CAP_DISCONN_REQ: err = l2cap_disconnect_req(conn, cmd, cmd_len, data); break; @@ -6834,11 +7310,13 @@ static void l2cap_chan_le_send_credits(struct l2cap_chan *chan) struct l2cap_le_credits pkt; u16 return_credits; - return_credits = ((chan->imtu / chan->mps) + 1) - chan->rx_credits; + return_credits = (chan->imtu / chan->mps) + 1; - if (!return_credits) + if (chan->rx_credits >= return_credits) return; + return_credits -= chan->rx_credits; + BT_DBG("chan %p returning %u credits to sender", chan, return_credits); chan->rx_credits += return_credits; @@ -6851,7 +7329,7 @@ static void l2cap_chan_le_send_credits(struct l2cap_chan *chan) l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt); } -static int l2cap_le_recv(struct l2cap_chan *chan, struct sk_buff *skb) +static int l2cap_ecred_recv(struct l2cap_chan *chan, struct sk_buff *skb) { int err; @@ -6866,7 +7344,7 @@ static int l2cap_le_recv(struct l2cap_chan *chan, struct sk_buff *skb) return err; } -static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) +static int l2cap_ecred_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) { int err; @@ -6914,7 +7392,7 @@ static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) } if (skb->len == sdu_len) - return l2cap_le_recv(chan, skb); + return l2cap_ecred_recv(chan, skb); chan->sdu = skb; chan->sdu_len = sdu_len; @@ -6946,7 +7424,7 @@ static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) skb = NULL; if (chan->sdu->len == chan->sdu_len) { - err = l2cap_le_recv(chan, chan->sdu); + err = l2cap_ecred_recv(chan, chan->sdu); if (!err) { chan->sdu = NULL; chan->sdu_last_frag = NULL; @@ -7007,7 +7485,8 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid, switch (chan->mode) { case L2CAP_MODE_LE_FLOWCTL: - if (l2cap_le_data_rcv(chan, skb) < 0) + case L2CAP_MODE_EXT_FLOWCTL: + if (l2cap_ecred_data_rcv(chan, skb) < 0) goto drop; goto done; @@ -7235,8 +7714,8 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, struct hci_dev *hdev; int err; - BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst, - dst_type, __le16_to_cpu(psm)); + BT_DBG("%pMR -> %pMR (type %u) psm 0x%4.4x mode 0x%2.2x", &chan->src, + dst, dst_type, __le16_to_cpu(psm), chan->mode); hdev = hci_get_route(dst, &chan->src, chan->src_type); if (!hdev) @@ -7264,6 +7743,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, case L2CAP_MODE_BASIC: break; case L2CAP_MODE_LE_FLOWCTL: + case L2CAP_MODE_EXT_FLOWCTL: break; case L2CAP_MODE_ERTM: case L2CAP_MODE_STREAMING: @@ -7389,6 +7869,38 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, } EXPORT_SYMBOL_GPL(l2cap_chan_connect); +static void l2cap_ecred_reconfigure(struct l2cap_chan *chan) +{ + struct l2cap_conn *conn = chan->conn; + struct { + struct l2cap_ecred_reconf_req req; + __le16 scid; + } pdu; + + pdu.req.mtu = cpu_to_le16(chan->imtu); + pdu.req.mps = cpu_to_le16(chan->mps); + pdu.scid = cpu_to_le16(chan->scid); + + chan->ident = l2cap_get_ident(conn); + + l2cap_send_cmd(conn, chan->ident, L2CAP_ECRED_RECONF_REQ, + sizeof(pdu), &pdu); +} + +int l2cap_chan_reconfigure(struct l2cap_chan *chan, __u16 mtu) +{ + if (chan->imtu > mtu) + return -EINVAL; + + BT_DBG("chan %p mtu 0x%4.4x", chan, mtu); + + chan->imtu = mtu; + + l2cap_ecred_reconfigure(chan); + + return 0; +} + /* ---- L2CAP interface with lower layer (HCI) ---- */ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) @@ -7600,7 +8112,8 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) else __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); } else if (chan->state == BT_CONNECT2 && - chan->mode != L2CAP_MODE_LE_FLOWCTL) { + !(chan->mode == L2CAP_MODE_EXT_FLOWCTL || + chan->mode == L2CAP_MODE_LE_FLOWCTL)) { struct l2cap_conn_rsp rsp; __u16 res, stat; diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 13d070e7738d..900da737e7d8 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -240,7 +240,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, return -EINVAL; } - if (chan->psm && bdaddr_type_is_le(chan->src_type)) + if (chan->psm && bdaddr_type_is_le(chan->src_type) && !chan->mode) chan->mode = L2CAP_MODE_LE_FLOWCTL; err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid), @@ -281,6 +281,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) switch (chan->mode) { case L2CAP_MODE_BASIC: case L2CAP_MODE_LE_FLOWCTL: + case L2CAP_MODE_EXT_FLOWCTL: break; case L2CAP_MODE_ERTM: case L2CAP_MODE_STREAMING: @@ -436,6 +437,8 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, opts.max_tx = chan->max_tx; opts.txwin_size = chan->tx_win; + BT_DBG("mode 0x%2.2x", chan->mode); + len = min_t(unsigned int, len, sizeof(opts)); if (copy_to_user(optval, (char *) &opts, len)) err = -EFAULT; @@ -703,6 +706,8 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, break; } + BT_DBG("mode 0x%2.2x", chan->mode); + chan->imtu = opts.imtu; chan->omtu = opts.omtu; chan->fcs = opts.fcs; @@ -932,7 +937,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, break; } - if (sk->sk_state == BT_CONNECTED) { + if (chan->mode == L2CAP_MODE_LE_FLOWCTL && + sk->sk_state == BT_CONNECTED) { err = -EISCONN; break; } @@ -942,7 +948,12 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, break; } - chan->imtu = opt; + if (chan->mode == L2CAP_MODE_EXT_FLOWCTL && + sk->sk_state == BT_CONNECTED) + err = l2cap_chan_reconfigure(chan, opt); + else + chan->imtu = opt; + break; default: @@ -997,7 +1008,11 @@ static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, if (sk->sk_state == BT_CONNECT2 && test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { - if (bdaddr_type_is_le(pi->chan->src_type)) { + if (pi->chan->mode == L2CAP_MODE_EXT_FLOWCTL) { + sk->sk_state = BT_CONNECTED; + pi->chan->state = BT_CONNECTED; + __l2cap_ecred_conn_rsp_defer(pi->chan); + } if (bdaddr_type_is_le(pi->chan->src_type)) { sk->sk_state = BT_CONNECTED; pi->chan->state = BT_CONNECTED; __l2cap_le_connect_rsp_defer(pi->chan); From patchwork Sat Dec 3 17:48:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cengiz Can X-Patchwork-Id: 1711728 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=GObn+1BP; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NPcl33SY6z23pH for ; Sun, 4 Dec 2022 04:49:35 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1p1Wdi-0007Rw-BO; Sat, 03 Dec 2022 17:49:26 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1p1Wdf-0007N6-Ei for kernel-team@lists.ubuntu.com; Sat, 03 Dec 2022 17:49:23 +0000 Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 18E7F3F1C3 for ; Sat, 3 Dec 2022 17:49:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1670089762; bh=NZjkmWZczWUNgp2tgRgIXFF8WWfFeLczg4dw6HZUsAo=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=GObn+1BPr0EPvH1t5klT0KJ/UDYLnKCn0ImxcBG5reLqGPuTRe8jeF38FL5MnHiOh DnFIURnerY4wAWbDA3QzKgR16g9zSjiwPDJusSHMiHt07UfP+lvtLTQqtwQiuQ46Rb R2HH8vb5ef8m9CGI33kBBacOoSpJ8Sjy3BI1qL8Dql23NVEeY7azTVjbtwuyeEBVLp yw6HSdbcO25QnV9w2OVS4snOzqT9+iHK1dn4CT4OxCID9sWJM5R4pTb2LOVclw09yZ xAiaBd9h0N2+lXg5IsjeGBotzYkuaXVuwp/RGh/MehbWpU1W/7Cv77S3JL09MlNWL4 Z0f1xXGvoqdlg== Received: by mail-wm1-f72.google.com with SMTP id e8-20020a05600c218800b003cf634f5280so2999598wme.8 for ; Sat, 03 Dec 2022 09:49:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NZjkmWZczWUNgp2tgRgIXFF8WWfFeLczg4dw6HZUsAo=; b=hFMN0vb5zOt906LSWQt6mjusUFzotpBscbFw6Z5SxQ4Qosgu9SbnXP3bf/UD2uEWFS B/J2idL4+DrBy5y5AhzU/LQotVmmcTktqKN+InVoy0NQenP2YvXuYa719BNw5Kz9Aqee PTaq4TeIfkL2Ph+Jy54ylT+4KORyGwAqLKtbIrrKMlLvW3Y+9jn3cWBiVRoEo7Pu8z1R CvoVYS4SXAB+fjmX1UxDVaqKXLiHIEti4FCDFPR8wkGfDAG6L8zJEXtOXJfo3hQ3ho2D 7jwK7gnxZ4DUxxDcvyZQ3jjeDM/bWmw3jJUSuH3KmvHEnJvPp7m1V+yP4nJzzit5equ2 cEmA== X-Gm-Message-State: ANoB5pm4HH0liQoVvaDTpX0UCSMpOZr/HXB0PJFhyef1AB7JyRv90TXY IWGglnwj8avadi/QtmVX9mRQRHBjwZMeIJxiCxyER6WOEkxjISdlcIp6lqoosF9NlHEtux9s14R Tl+laCS3g8EmlSqUe7oVRvHxydYLVwG14e/AfrEa0Hw== X-Received: by 2002:adf:d08c:0:b0:236:783e:5947 with SMTP id y12-20020adfd08c000000b00236783e5947mr45994303wrh.168.1670089761512; Sat, 03 Dec 2022 09:49:21 -0800 (PST) X-Google-Smtp-Source: AA0mqf7xKQ7jCCze94QyuGwJoXJle9daVShZ8U32HASGof5Nptws5/FeP+kx33M/rSfY/9h2jZZ3/A== X-Received: by 2002:adf:d08c:0:b0:236:783e:5947 with SMTP id y12-20020adfd08c000000b00236783e5947mr45994299wrh.168.1670089761282; Sat, 03 Dec 2022 09:49:21 -0800 (PST) Received: from localhost ([92.44.145.54]) by smtp.gmail.com with ESMTPSA id e14-20020adff34e000000b0024228b0b932sm12196131wrp.27.2022.12.03.09.49.20 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 03 Dec 2022 09:49:20 -0800 (PST) From: Cengiz Can To: kernel-team@lists.ubuntu.com Subject: [SRU Bionic v2 6/8] Bluetooth: L2CAP: Add definitions for Enhanced Credit Based Mode Date: Sat, 3 Dec 2022 20:48:41 +0300 Message-Id: <20221203174842.543278-7-cengiz.can@canonical.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221203174842.543278-1-cengiz.can@canonical.com> References: <20221203174842.543278-1-cengiz.can@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Luiz Augusto von Dentz This introduces the definitions for the new L2CAP mode called Enhanced Credit Based Mode. Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Marcel Holtmann CVE-2022-42896 (cherry picked from commit 145720963b6c68d0c4054112c09050995259b8f8) Signed-off-by: Cengiz Can --- include/net/bluetooth/l2cap.h | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 255a30597b12..ada682b8a37e 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -119,6 +119,10 @@ struct l2cap_conninfo { #define L2CAP_LE_CONN_REQ 0x14 #define L2CAP_LE_CONN_RSP 0x15 #define L2CAP_LE_CREDITS 0x16 +#define L2CAP_ECRED_CONN_REQ 0x17 +#define L2CAP_ECRED_CONN_RSP 0x18 +#define L2CAP_ECRED_RECONF_REQ 0x19 +#define L2CAP_ECRED_RECONF_RSP 0x1a /* L2CAP extended feature mask */ #define L2CAP_FEAT_FLOWCTL 0x00000001 @@ -359,6 +363,7 @@ struct l2cap_conf_rfc { * ever be used in the BR/EDR configuration phase. */ #define L2CAP_MODE_LE_FLOWCTL 0x80 +#define L2CAP_MODE_EXT_FLOWCTL 0x81 struct l2cap_conf_efs { __u8 id; @@ -483,6 +488,39 @@ struct l2cap_le_credits { __le16 credits; } __packed; +#define L2CAP_ECRED_MIN_MTU 64 +#define L2CAP_ECRED_MIN_MPS 64 + +struct l2cap_ecred_conn_req { + __le16 psm; + __le16 mtu; + __le16 mps; + __le16 credits; + __le16 scid[0]; +} __packed; + +struct l2cap_ecred_conn_rsp { + __le16 mtu; + __le16 mps; + __le16 credits; + __le16 result; + __le16 dcid[0]; +}; + +struct l2cap_ecred_reconf_req { + __le16 mtu; + __le16 mps; + __le16 scid[0]; +} __packed; + +#define L2CAP_RECONF_SUCCESS 0x0000 +#define L2CAP_RECONF_INVALID_MTU 0x0001 +#define L2CAP_RECONF_INVALID_MPS 0x0002 + +struct l2cap_ecred_reconf_rsp { + __le16 result; +} __packed; + /* ----- L2CAP channels and connections ----- */ struct l2cap_seq_list { __u16 head; @@ -726,6 +764,7 @@ enum { FLAG_EFS_ENABLE, FLAG_DEFER_SETUP, FLAG_LE_CONN_REQ_SENT, + FLAG_ECRED_CONN_REQ_SENT, FLAG_PENDING_SECURITY, FLAG_HOLD_HCI_CONN, }; From patchwork Sat Dec 3 17:48:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Cengiz Can X-Patchwork-Id: 1711729 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=e0PqWT3K; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NPcl60sRWz23np for ; Sun, 4 Dec 2022 04:49:38 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1p1Wdl-0007WX-5S; Sat, 03 Dec 2022 17:49:29 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1p1Wdg-0007Oq-6s for kernel-team@lists.ubuntu.com; Sat, 03 Dec 2022 17:49:24 +0000 Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id BF3DC3F1C3 for ; Sat, 3 Dec 2022 17:49:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1670089763; bh=9DipQEZEsTBSfZSntrKRcL+IoPAHN/dT6RQ4BPr37Nk=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=e0PqWT3KWdG90Emq/vtpYHfMDNemBpv6QlIGVAz06d7MZFAnzA0IW6ZkrD/VKFDn9 sxoZrbUMdZ8NciRllKALtcRzJwnT47RgxvTwOK0VyG8wR3WGs8q6LmNnq5BiVMtkkV dt4IfI3BK52ffsA8SnvDRceAUfi06kw4qV/q7zUbK2G2HpUFs7PGDIQA1kK6mZ/IYr VVZ9zJ/wRIUDD2ORYgUrbpdcnpG2u52OTO8awOWduAMSMn8vrkERkTHAxULF4pMfPO 2iZRP5Zs3S8c6ITqVFSNOCEFEjF3hhjwdD0gm1iUm45spQe5mJt48xwQ77biBSde8Z d8xbKGb4fP5/Q== Received: by mail-wm1-f70.google.com with SMTP id v125-20020a1cac83000000b003cfa148576dso4228918wme.3 for ; Sat, 03 Dec 2022 09:49:23 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9DipQEZEsTBSfZSntrKRcL+IoPAHN/dT6RQ4BPr37Nk=; b=OeQ4ykE65Htikc24pUe8HGIv3tP0ollViv/M2ats3PvFefPUHlRcRuLYvxyvIX78fL LVm4VI4/2wtBYsk3HfAeLu3ASfeh9QTq6q4nKtWXt3G3rKiNy4UOJAYnWWXRhHweSxkG ZXdU+kwmkLli3OAvbM5LnQmW53FWRxKK2Vm3KGdsMfWn+Bf5ZXGBL3wg1Lphijx0EIRA FtvHvFwPrRGwr7y/Sr8piHJLtf0mS0elag4f9q2v2NFi7hrT3PqOZLRLQrQWhyJdZ3A/ q99u2SXaMv0z/gmkVqFADD/fLNbgNbdZIGDJfrDlSLuYU46p0IuslfsD5jlbFhxLFdOJ FY0g== X-Gm-Message-State: ANoB5pnG6AqYPJeTweMJoxlI2eysVw6Sd11zZx+loqO2CnhGEi85mBGK 01hH5mjG/Lblv/0gWo+cNlocYtvwUrBt/QhNjP32H93sqlcWpUXjeg1Hqglq/uTw7QL3sRDCqAR vA+gFlSdYreifOWiDnXC/dYfwNSWe8uCk5sBVzgvUyg== X-Received: by 2002:a1c:7709:0:b0:3cf:6a83:c7a3 with SMTP id t9-20020a1c7709000000b003cf6a83c7a3mr15523466wmi.21.1670089763300; Sat, 03 Dec 2022 09:49:23 -0800 (PST) X-Google-Smtp-Source: AA0mqf6f1T/HlLiB3PqgP7/ktRS96pTbLIicrvEOJzxdAw8ZzICId96NQ0YFR+K5EKEYlhQY2tUNEA== X-Received: by 2002:a1c:7709:0:b0:3cf:6a83:c7a3 with SMTP id t9-20020a1c7709000000b003cf6a83c7a3mr15523457wmi.21.1670089763094; Sat, 03 Dec 2022 09:49:23 -0800 (PST) Received: from localhost ([92.44.145.54]) by smtp.gmail.com with ESMTPSA id n15-20020a05600c3b8f00b003c6deb5c1edsm13682519wms.45.2022.12.03.09.49.22 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 03 Dec 2022 09:49:22 -0800 (PST) From: Cengiz Can To: kernel-team@lists.ubuntu.com Subject: [SRU Bionic v2 7/8] Bluetooth: L2CAP: Fix accepting connection request for invalid SPSM Date: Sat, 3 Dec 2022 20:48:42 +0300 Message-Id: <20221203174842.543278-8-cengiz.can@canonical.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221203174842.543278-1-cengiz.can@canonical.com> References: <20221203174842.543278-1-cengiz.can@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Luiz Augusto von Dentz The Bluetooth spec states that the valid range for SPSM is from 0x0001-0x00ff so it is invalid to accept values outside of this range: BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part A page 1059: Table 4.15: L2CAP_LE_CREDIT_BASED_CONNECTION_REQ SPSM ranges CVE: CVE-2022-42896 CC: stable@vger.kernel.org Reported-by: Tamás Koczka Signed-off-by: Luiz Augusto von Dentz Reviewed-by: Tedd Ho-Jeong An (cherry picked from commit 711f8c3fb3db61897080468586b970c87c61d9e4) Signed-off-by: Cengiz Can --- net/bluetooth/l2cap_core.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 3c0eff6e2cd1..cb3d81cd4d36 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -5668,6 +5668,19 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn, BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm), scid, mtu, mps); + /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part A + * page 1059: + * + * Valid range: 0x0001-0x00ff + * + * Table 4.15: L2CAP_LE_CREDIT_BASED_CONNECTION_REQ SPSM ranges + */ + if (!psm || __le16_to_cpu(psm) > L2CAP_PSM_LE_DYN_END) { + result = L2CAP_CR_LE_BAD_PSM; + chan = NULL; + goto response; + } + /* Check if we have socket listening on psm */ pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src, &conn->hcon->dst, LE_LINK); @@ -5846,6 +5859,18 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn, psm = req->psm; credits = 0; + /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part A + * page 1059: + * + * Valid range: 0x0001-0x00ff + * + * Table 4.15: L2CAP_LE_CREDIT_BASED_CONNECTION_REQ SPSM ranges + */ + if (!psm || __le16_to_cpu(psm) > L2CAP_PSM_LE_DYN_END) { + result = L2CAP_CR_LE_BAD_PSM; + goto response; + } + BT_DBG("psm 0x%2.2x mtu %u mps %u", __le16_to_cpu(psm), mtu, mps); memset(&pdu, 0, sizeof(pdu)); From patchwork Sat Dec 3 17:48:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cengiz Can X-Patchwork-Id: 1711730 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=TFAXwgQ1; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NPcl95RhYz23np for ; Sun, 4 Dec 2022 04:49:41 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1p1Wdo-0007dh-Pr; Sat, 03 Dec 2022 17:49:32 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1p1Wdi-0007Rt-Uw for kernel-team@lists.ubuntu.com; Sat, 03 Dec 2022 17:49:27 +0000 Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id A1E943F1C3 for ; Sat, 3 Dec 2022 17:49:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1670089765; bh=M2B5I49VWGeYNWHOrUgBjvCQqEQzdXCF4JHazDPyyoY=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=TFAXwgQ1VIvkKIJCcDXl8ihqO9B9IUD2f8MOQ1AqDjr7KuyvHmMOje3YVb+dY1JBk TZXhHvaYO2wnUgjAIk2A20ZjUb6AsyQBeQrZlhz4pU/krIAjkePuBDQduKWxP2XPj3 ybOtHGX6si4QpemsgXh7GobR2o6nKXDO8RVMRKVFPQ2n6JgV1jIWgfEpbjZI0KFnVK 4RDxGYYthAvnbqxjve6nibIkSaZdbx3xDLXEfNXliPzKyK8N6wCugfsIAd5UCOTmzh dl5mzynd27p3Mz19X3uMr+EifsCzSLAFa2DfjVGrUWowGhHtr1Ga/MWRBE/JHSMQPv d+JvK03xdzaOg== Received: by mail-wr1-f69.google.com with SMTP id v14-20020adf8b4e000000b0024174021277so1631870wra.13 for ; Sat, 03 Dec 2022 09:49:25 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=M2B5I49VWGeYNWHOrUgBjvCQqEQzdXCF4JHazDPyyoY=; b=cMEvBVRiwok56Kv3T8NLtjSgKKjAx7pdnldd43zE1ANR8yibzTRe1qV6Wx8NCOKmDO wGpyMFFDKz14LODmHXvulbK8LG6geZRwn9xHqnerdP+dhmOL/5K/JdI2xMEszWY6L+K0 qEgF5Vqxo8OsCS7VXZH1M5pccg1872k1z5O2l/nY+ocWMxBuQgCCfjmlPnQnnSUXYbOe kye44UROTUfaId7mnmC5Klvu1FZqJ2UBGRfP5/7TD4hZquBASKDAdKOqxpbexCgK2DLm EPDESewIFcLMFASdSKhmDKRg/RSgk1bNAGq40jI4MBk64nRKi0hRy2h2xUvp4rDn6Yby BNfw== X-Gm-Message-State: ANoB5pkQt9Y9AN5amBvQk/SK0yzVQAE9+XE9x8kF2xT4XiGxq8/eh3Nw cK2WT1aUW4bc8z8x686n/QHBz6OnUe5soPxsut0xomSgpTCpPCdDouhFT8Y+f6pPXTRfaJLs8Ka nqAeOHDIUpJl5fm8XVmSeBZYvz0Qutk/ODWZ1Dh6BGg== X-Received: by 2002:a05:600c:a52:b0:3d0:73ab:461d with SMTP id c18-20020a05600c0a5200b003d073ab461dmr12105026wmq.73.1670089765101; Sat, 03 Dec 2022 09:49:25 -0800 (PST) X-Google-Smtp-Source: AA0mqf5LQcYx7LkLzZWs5VZZ/ziAjQ9XmbLwoYePBXAQ7xaUBsz5zG8vFfviBcoBbWfglMiipNdvtA== X-Received: by 2002:a05:600c:a52:b0:3d0:73ab:461d with SMTP id c18-20020a05600c0a5200b003d073ab461dmr12105018wmq.73.1670089764860; Sat, 03 Dec 2022 09:49:24 -0800 (PST) Received: from localhost ([92.44.145.54]) by smtp.gmail.com with ESMTPSA id b6-20020a5d6346000000b00242442c8ebdsm5074373wrw.111.2022.12.03.09.49.24 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 03 Dec 2022 09:49:24 -0800 (PST) From: Cengiz Can To: kernel-team@lists.ubuntu.com Subject: [SRU Bionic v2 8/8] Bluetooth: L2CAP: Fix l2cap_global_chan_by_psm Date: Sat, 3 Dec 2022 20:48:43 +0300 Message-Id: <20221203174842.543278-9-cengiz.can@canonical.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221203174842.543278-1-cengiz.can@canonical.com> References: <20221203174842.543278-1-cengiz.can@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Luiz Augusto von Dentz l2cap_global_chan_by_psm shall not return fixed channels as they are not meant to be connected by (S)PSM. Signed-off-by: Luiz Augusto von Dentz Reviewed-by: Tedd Ho-Jeong An CVE-2022-42896 (cherry picked from commit f937b758a188d6fd328a81367087eddbb2fce50f) Signed-off-by: Cengiz Can --- net/bluetooth/l2cap_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index cb3d81cd4d36..144e14e954db 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1900,7 +1900,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, if (link_type == LE_LINK && c->src_type == BDADDR_BREDR) continue; - if (c->psm == psm) { + if (c->chan_type != L2CAP_CHAN_FIXED && c->psm == psm) { int src_match, dst_match; int src_any, dst_any;