From patchwork Tue Aug 13 17:26:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Connor Kuehl X-Patchwork-Id: 1146521 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 467KQM3lPsz9sND; Wed, 14 Aug 2019 03:26:50 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1hxaZJ-0002M5-BR; Tue, 13 Aug 2019 17:26:45 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1hxaZH-0002Lb-Ne for kernel-team@lists.ubuntu.com; Tue, 13 Aug 2019 17:26:43 +0000 Received: from mail-pg1-f197.google.com ([209.85.215.197]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1hxaZH-0005JE-7L for kernel-team@lists.ubuntu.com; Tue, 13 Aug 2019 17:26:43 +0000 Received: by mail-pg1-f197.google.com with SMTP id b18so66847318pgg.8 for ; Tue, 13 Aug 2019 10:26:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=wfAn/emTYVLOnCqeqAPNho6OsBC1p5XvkjvdReo0FIw=; b=WiBndkIA3J7zW2pwHfOL19X/M9H3MC+UHwfa/r8S8U2vLDFDd/kQuFAoCZlSlyvTNg SACJ+qdm0/ER6h3A7fMvEh9QM8nUlRVnYN8PyJqcmNXcxuWzpb/JMzYoOm3dfh02YntL 2+PCDyuimsETD4G9VwK0QZPDSIS1OKvJP7dcyZ/qfluP9ACMR8Awr/GHyuaPhJeYwjxZ BDoqPknG38Dq11ycVkFDjjGLlDRGyxEz/x64nEiPrfsEFE8zq/5nV5GEu2n6VF841baC HApGEBdMlugJ/w5VyH7IW2bAsobke+6Cmynt8fl3osWQDGxSeqlBCi9rWAV23GMgpeuZ wwBw== X-Gm-Message-State: APjAAAXPqZbSRuPo4FYaA00huuWWnmS+zleYBfe/XjP/roW33Qg+sCiZ dDV7cZE0JWEpJdh6RaVu0Ij12hAPsl1OarmJSmF4nMXOWnGGNbyn11YeNDIxrXrsJ3O42oEfjVm uw917l2ph684dlkluP1AHcI2u6dZpmUyHCaUTzklwDw== X-Received: by 2002:a17:90a:3aaf:: with SMTP id b44mr3260914pjc.87.1565717201486; Tue, 13 Aug 2019 10:26:41 -0700 (PDT) X-Google-Smtp-Source: APXvYqzVKzayHUo2OYJMKB3u4Mg+TInw4+dJ1IvBqi98z7IUjL5Tg+nCnnXC5R2tVRs2veWJJMTcAw== X-Received: by 2002:a17:90a:3aaf:: with SMTP id b44mr3260897pjc.87.1565717201170; Tue, 13 Aug 2019 10:26:41 -0700 (PDT) Received: from localhost.localdomain (c-71-63-131-226.hsd1.or.comcast.net. [71.63.131.226]) by smtp.gmail.com with ESMTPSA id l124sm109353184pgl.54.2019.08.13.10.26.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Aug 2019 10:26:40 -0700 (PDT) From: Connor Kuehl To: kernel-team@lists.ubuntu.com Subject: [Xenial][SRU][CVE-2019-10207][PATCH v2] Bluetooth: hci_uart: check for missing tty operations Date: Tue, 13 Aug 2019 10:26:39 -0700 Message-Id: <20190813172639.23747-1-connor.kuehl@canonical.com> X-Mailer: git-send-email 2.20.1 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: Vladis Dronov CVE-2019-10207 Certain ttys operations (pty_unix98_ops) lack tiocmget() and tiocmset() functions which are called by the certain HCI UART protocols (hci_ath, hci_bcm, hci_intel, hci_mrvl, hci_qca) via hci_uart_set_flow_control() or directly. This leads to an execution at NULL and can be triggered by an unprivileged user. Fix this by adding a helper function and a check for the missing tty operations in the protocols code. This fixes CVE-2019-10207. The Fixes: lines list commits where calls to tiocm[gs]et() or hci_uart_set_flow_control() were added to the HCI UART protocols. Link: https://syzkaller.appspot.com/bug?id=1b42faa2848963564a5b1b7f8c837ea7b55ffa50 Reported-by: syzbot+79337b501d6aa974d0f6@syzkaller.appspotmail.com Cc: stable@vger.kernel.org # v2.6.36+ Fixes: b3190df62861 ("Bluetooth: Support for Atheros AR300x serial chip") Fixes: 118612fb9165 ("Bluetooth: hci_bcm: Add suspend/resume PM functions") Fixes: ff2895592f0f ("Bluetooth: hci_intel: Add Intel baudrate configuration support") Fixes: 162f812f23ba ("Bluetooth: hci_uart: Add Marvell support") Fixes: fa9ad876b8e0 ("Bluetooth: hci_qca: Add support for Qualcomm Bluetooth chip wcn3990") Signed-off-by: Vladis Dronov Signed-off-by: Marcel Holtmann Reviewed-by: Yu-Chen, Cho Tested-by: Yu-Chen, Cho Signed-off-by: Linus Torvalds (backported from commit b36a1552d7319bbfd5cf7f08726c23c5c66d4f73) [ Connor Kuehl: drivers/bluetooth/hci_mrvl.c does not exist in Xenial, so that hunk was dropped. The qca_open() function had a very minor merge conflict but that's just because the kzalloc invocation used GFP_KERNEL in the patch but Xenial uses GFP_ATOMIC. The check on the 'serdev' data member was also dropped from hci_uart_has_flow_control() because it doesn't exist in Xenial and there is no reason to backport the serdev commit(s) since this fix has no functional dependency on serdev (none of its functions are called). ] Signed-off-by: Connor Kuehl Acked-by: Stefan Bader --- v1 -> v2: * Dropped the commit that introduced serdev which let me: * Drop the if statement checking for the serdev data member on the hci_uart structure drivers/bluetooth/hci_ath.c | 3 +++ drivers/bluetooth/hci_bcm.c | 3 +++ drivers/bluetooth/hci_intel.c | 3 +++ drivers/bluetooth/hci_ldisc.c | 9 +++++++++ drivers/bluetooth/hci_qca.c | 3 +++ drivers/bluetooth/hci_uart.h | 1 + 6 files changed, 22 insertions(+) diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index d776dfd51478..16f2131687e5 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c @@ -101,6 +101,9 @@ static int ath_open(struct hci_uart *hu) BT_DBG("hu %p", hu); + if (!hci_uart_has_flow_control(hu)) + return -EOPNOTSUPP; + ath = kzalloc(sizeof(*ath), GFP_KERNEL); if (!ath) return -ENOMEM; diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index f9b569ef3dd7..20a1b4d1fd09 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -279,6 +279,9 @@ static int bcm_open(struct hci_uart *hu) bt_dev_dbg(hu->hdev, "hu %p", hu); + if (!hci_uart_has_flow_control(hu)) + return -EOPNOTSUPP; + bcm = kzalloc(sizeof(*bcm), GFP_KERNEL); if (!bcm) return -ENOMEM; diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c index f40a86960fde..772c91d843ff 100644 --- a/drivers/bluetooth/hci_intel.c +++ b/drivers/bluetooth/hci_intel.c @@ -407,6 +407,9 @@ static int intel_open(struct hci_uart *hu) BT_DBG("hu %p", hu); + if (!hci_uart_has_flow_control(hu)) + return -EOPNOTSUPP; + intel = kzalloc(sizeof(*intel), GFP_KERNEL); if (!intel) return -ENOMEM; diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 96bcec5598c2..d5db2332eb6f 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -257,6 +257,15 @@ static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb) return 0; } +/* Check the underlying device or tty has flow control support */ +bool hci_uart_has_flow_control(struct hci_uart *hu) +{ + if (hu->tty->driver->ops->tiocmget && hu->tty->driver->ops->tiocmset) + return true; + + return false; +} + /* Flow control or un-flow control the device */ void hci_uart_set_flow_control(struct hci_uart *hu, bool enable) { diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index ecfb9ed2cff6..6b5b9ae6e809 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -390,6 +390,9 @@ static int qca_open(struct hci_uart *hu) BT_DBG("hu %p qca_open", hu); + if (!hci_uart_has_flow_control(hu)) + return -EOPNOTSUPP; + qca = kzalloc(sizeof(struct qca_data), GFP_ATOMIC); if (!qca) return -ENOMEM; diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h index 82c92f1b65b4..ce00c02eb63f 100644 --- a/drivers/bluetooth/hci_uart.h +++ b/drivers/bluetooth/hci_uart.h @@ -105,6 +105,7 @@ int hci_uart_tx_wakeup(struct hci_uart *hu); int hci_uart_init_ready(struct hci_uart *hu); void hci_uart_init_tty(struct hci_uart *hu); void hci_uart_set_baudrate(struct hci_uart *hu, unsigned int speed); +bool hci_uart_has_flow_control(struct hci_uart *hu); void hci_uart_set_flow_control(struct hci_uart *hu, bool enable); void hci_uart_set_speeds(struct hci_uart *hu, unsigned int init_speed, unsigned int oper_speed);