Received: by 2002:a25:f815:0:0:0:0:0 with SMTP id u21csp2245663ybd; Mon, 24 Jun 2019 03:13:33 -0700 (PDT) X-Google-Smtp-Source: APXvYqztoohympStg8ORr8Al95qUx3/hK0u6np4T7Sn492VWCKOm4rCGlBaDr/P176EfDQaPf+K+ X-Received: by 2002:a17:90a:32ed:: with SMTP id l100mr23610012pjb.11.1561371213576; Mon, 24 Jun 2019 03:13:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561371213; cv=none; d=google.com; s=arc-20160816; b=uUkb/VMm1w20kbdyOc204agNEg0OuTC2AKfBfDZ4QyUUjnBe8HHm7EcW/DHVAMqltZ a4Zc+dr/hwDI+fdYx50ckfnfIwmNzPKAe+KCAYnKmw77tT4rRG2TCZClDjYVzmIhrJ8+ UddSBAPDM0fkw6NwuoJCYfHbWUKWNyyqh5eHhrI1O0qOkIOfasiSAgdSunRni/MtWufb i9ORV/Hv0LCo7NFIc6yMWwaODFbRy/BlkXCQ7xp3qkcS5jCBBgcAP9NX0PjJcKJ8l7L7 rtO1jl0p+hPkZ05fJE0YTfx0X2BWt5Nv+Z7Vw/zILFhUt/hhr/di4fYj/EtFuayeVz1m Iqcw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=6pQLBmTIxEM+Ef3czjKXGDZLSw6HrHt0XmsQLbBgwlg=; b=wUVGQKgWgdSVUmwm4m0uPQiCdZA44SfHcUJx1C18WI1b8yEcRvho2AVde9uqmeAckx cFot8kzOPeRpt9UbnOwIlI7r4o7tZXhNjIJrtzgIw6j30J6KhbJcHXPmpX5DN4XCybp6 ls9gp/vgLFD8Hp1btuccX3fUoaxkbjtHW8yAOV0kDyIeppb/1WZ8uykXumx0FpHlKZ6G QC5aljE8wXyYuFIpbGQQQznxg6870h0aeNKoL1UGp3jb0epU7tu/eOWLa4kMt38T+q+r +6525/nPkUbwP9Rqt6syxDVEhlqfY+uJCw/S1k3Tu4IvDyqEV48VRZu/HpCvNM6zif5T 7f0Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=F2BaHKtq; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i5si9324241pgq.412.2019.06.24.03.13.17; Mon, 24 Jun 2019 03:13:33 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=F2BaHKtq; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730051AbfFXKGJ (ORCPT + 99 others); Mon, 24 Jun 2019 06:06:09 -0400 Received: from mail.kernel.org ([198.145.29.99]:38208 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730038AbfFXKGH (ORCPT ); Mon, 24 Jun 2019 06:06:07 -0400 Received: from localhost (f4.8f.5177.ip4.static.sl-reverse.com [119.81.143.244]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 776AF208E3; Mon, 24 Jun 2019 10:06:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1561370765; bh=85Qat+uLgkdXkm5ajbXJT6yXkXNjzM1k5wk2FV0uvbI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=F2BaHKtqn22Z4d9wi4NllwyTSCj7MQEqgwp/sOK3dKYEYeYHSJnXZXp3mDNPrMHnn A9kaSC3XfbJrA/TMuvSBBtboXaQbTuTmBHyIXKssGbnBdvYt3Pm7bgs1BEs/V7F8AA P+CTbcPgZJePPKj6ANlMJlgNoOR5atLsvcNGbh30= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Marcel Holtmann , Linus Torvalds Subject: [PATCH 4.19 82/90] Bluetooth: Fix regression with minimum encryption key size alignment Date: Mon, 24 Jun 2019 17:57:12 +0800 Message-Id: <20190624092319.296342984@linuxfoundation.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190624092313.788773607@linuxfoundation.org> References: <20190624092313.788773607@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Marcel Holtmann commit 693cd8ce3f882524a5d06f7800dd8492411877b3 upstream. When trying to align the minimum encryption key size requirement for Bluetooth connections, it turns out doing this in a central location in the HCI connection handling code is not possible. Original Bluetooth version up to 2.0 used a security model where the L2CAP service would enforce authentication and encryption. Starting with Bluetooth 2.1 and Secure Simple Pairing that model has changed into that the connection initiator is responsible for providing an encrypted ACL link before any L2CAP communication can happen. Now connecting Bluetooth 2.1 or later devices with Bluetooth 2.0 and before devices are causing a regression. The encryption key size check needs to be moved out of the HCI connection handling into the L2CAP channel setup. To achieve this, the current check inside hci_conn_security() has been moved into l2cap_check_enc_key_size() helper function and then called from four decisions point inside L2CAP to cover all combinations of Secure Simple Pairing enabled devices and device using legacy pairing and legacy service security model. Fixes: d5bb334a8e17 ("Bluetooth: Align minimum encryption key size for LE and BR/EDR connections") Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=203643 Signed-off-by: Marcel Holtmann Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- net/bluetooth/hci_conn.c | 18 +++++++++--------- net/bluetooth/l2cap_core.c | 33 ++++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 14 deletions(-) --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -1276,14 +1276,6 @@ int hci_conn_check_link_mode(struct hci_ !test_bit(HCI_CONN_ENCRYPT, &conn->flags)) return 0; - /* The minimum encryption key size needs to be enforced by the - * host stack before establishing any L2CAP connections. The - * specification in theory allows a minimum of 1, but to align - * BR/EDR and LE transports, a minimum of 7 is chosen. - */ - if (conn->enc_key_size < HCI_MIN_ENC_KEY_SIZE) - return 0; - return 1; } @@ -1400,8 +1392,16 @@ auth: return 0; encrypt: - if (test_bit(HCI_CONN_ENCRYPT, &conn->flags)) + if (test_bit(HCI_CONN_ENCRYPT, &conn->flags)) { + /* Ensure that the encryption key size has been read, + * otherwise stall the upper layer responses. + */ + if (!conn->enc_key_size) + return 0; + + /* Nothing else needed, all requirements are met */ return 1; + } hci_conn_encrypt(conn); return 0; --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1340,6 +1340,21 @@ static void l2cap_request_info(struct l2 sizeof(req), &req); } +static bool l2cap_check_enc_key_size(struct hci_conn *hcon) +{ + /* The minimum encryption key size needs to be enforced by the + * host stack before establishing any L2CAP connections. The + * specification in theory allows a minimum of 1, but to align + * BR/EDR and LE transports, a minimum of 7 is chosen. + * + * This check might also be called for unencrypted connections + * that have no key size requirements. Ensure that the link is + * actually encrypted before enforcing a key size. + */ + return (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags) || + hcon->enc_key_size > HCI_MIN_ENC_KEY_SIZE); +} + static void l2cap_do_start(struct l2cap_chan *chan) { struct l2cap_conn *conn = chan->conn; @@ -1357,9 +1372,14 @@ static void l2cap_do_start(struct l2cap_ if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)) return; - if (l2cap_chan_check_security(chan, true) && - __l2cap_no_conn_pending(chan)) + if (!l2cap_chan_check_security(chan, true) || + !__l2cap_no_conn_pending(chan)) + return; + + if (l2cap_check_enc_key_size(conn->hcon)) l2cap_start_connection(chan); + else + __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); } static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) @@ -1438,7 +1458,10 @@ static void l2cap_conn_start(struct l2ca continue; } - l2cap_start_connection(chan); + if (l2cap_check_enc_key_size(conn->hcon)) + l2cap_start_connection(chan); + else + l2cap_chan_close(chan, ECONNREFUSED); } else if (chan->state == BT_CONNECT2) { struct l2cap_conn_rsp rsp; @@ -7455,7 +7478,7 @@ static void l2cap_security_cfm(struct hc } if (chan->state == BT_CONNECT) { - if (!status) + if (!status && l2cap_check_enc_key_size(hcon)) l2cap_start_connection(chan); else __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); @@ -7464,7 +7487,7 @@ static void l2cap_security_cfm(struct hc struct l2cap_conn_rsp rsp; __u16 res, stat; - if (!status) { + if (!status && l2cap_check_enc_key_size(hcon)) { if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { res = L2CAP_CR_PEND; stat = L2CAP_CS_AUTHOR_PEND;