From patchwork Thu Feb 4 23:50:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lino Sanfilippo X-Patchwork-Id: 377624 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.0 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, MIME_BASE64_TEXT, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AD017C433E9 for ; Thu, 4 Feb 2021 23:53:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 79BB764FB0 for ; Thu, 4 Feb 2021 23:53:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231145AbhBDXw7 (ORCPT ); Thu, 4 Feb 2021 18:52:59 -0500 Received: from mout.gmx.net ([212.227.15.19]:41219 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230360AbhBDXw4 (ORCPT ); Thu, 4 Feb 2021 18:52:56 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1612482671; bh=/dQdgnl91QMwGWsN3AocD1I7jQSldVChIt8irvbVrVs=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=UhV/4HjxKeqOC8ogUDV5RoEFSXG3KUHja28qKNt2h0enjorHMO2ZzSLirRgUNolZ+ IVbtsIthG5fVOIb6yCFuucDQqMewTdKscxtZhDS3BSZFnmNaqfFg7G+gFcdtW5lgYw 5EUDWAzGxAZFlTv9cXMFzPiHhP2ZxO4RmtGvtWc0= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from Venus.fritz.box ([78.42.220.31]) by mail.gmx.net (mrgmx005 [212.227.17.190]) with ESMTPSA (Nemesis) id 1Mqs0R-1llbGI23e5-00munc; Fri, 05 Feb 2021 00:51:11 +0100 From: Lino Sanfilippo To: peterhuewe@gmx.de, jarkko@kernel.org Cc: jgg@ziepe.ca, stefanb@linux.vnet.ibm.com, James.Bottomley@hansenpartnership.com, stable@vger.kernel.org, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, LinoSanfilippo@gmx.de, Lino Sanfilippo Subject: [PATCH v3 1/2] tpm: fix reference counting for struct tpm_chip Date: Fri, 5 Feb 2021 00:50:42 +0100 Message-Id: <1612482643-11796-2-git-send-email-LinoSanfilippo@gmx.de> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1612482643-11796-1-git-send-email-LinoSanfilippo@gmx.de> References: <1612482643-11796-1-git-send-email-LinoSanfilippo@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:kTi43lxvy4R7S+d8RjF8xafoGxVwhAvNPrzoSl6InkrziF2Zn/8 t5Cobn2pSwW0xz7bR1ZBhpe9uIdp8slbHMCqle6aMNXLhV+p5f2cnRtnax2kRJ/BtPm7hgi tvK71PgehBgJFLsLJR8qr3KEsBALaC09a9VKUpr4VXQhAaTkYaP7EzmRhhKbmzNrYBH41zR 0yn39y/43msFjU4NyA38A== X-UI-Out-Filterresults: notjunk:1; V03:K0:v9CqxU6qGJU=:Ni0CiCUin3/dnavYA+cksX P4gDoyXg/dCd2VpXzkjxqNUmNPvco13/ydgWl/wOa8+pMqcWCafdkl438gDUbSmAKxCNxE9bF y9iIspVOsZz9ruZdJzDtAvKHWSaPtO7qLepW+imhNlW17KcxI1YB0Log1qvO/mfMRgIgGXcxb PTvPVSNY/715hB4GEeRFvjdAX9rqdPnMDTjG248bAyHALap4iNebxGDHRfmkrL7oznqSzKRn4 XgCw/LPNYj6uPDipVLL0vIjrVRLnKNwKoMP8VFSG3PZfTDe1QOFEaCGeIaUFaeu0v57fosMCB 3EVz6dgWd04HjmXnZWYIEkZy7rP7FLR7TuFSzG9p2eg+rhpsDLQWwwgPsuFpPCKICNybNAuFZ s+MCgpeaDb0bplICOzjNHJoDk377xnw+YKcq7ustGQFdj1jn6kPQXvd3P9guGl+qX3rtMhjDL ntj+zrCTRSbCbxtQQ/MoCFrBKRJl5b51xlth5bvEauKxe8BBi6I4W7qFuRIkynGy7cOGmRnxX IUHpvFSS+JirM/7r7P1E/LHHFUmMK/a9MrmaZZnTFHzjpnK7hCvTYex0FmjwQDu9hjY70KukT 8sBQERNddOGTkzm2d2+p25h67Pcm1r5dFHC9bAnHxT8sp52BdfdtamONCoTX5yuR8psoKSlha BdaWGRprWHxUhO6am7T3ZVdquewI2WQ5rAr5fEuhYvjcpZ6HffDmvDLS2zi8ERA27dvmkLVOF hCbxGAAIpKCNBwvLgD1594Rlx7B0mWnBrSFdsz0KghCuc+xL0Z74AuT0LSi9M2mf+tBQsJ+/n K/9iEZUlyuZe3jLqM1R0Bx2YEP9rzWI7adOR9zyKJmtA878VQNHOfR0Z4wxESkY1+VjgxqeyM 5Vc5YzJjQGA7GJzJ5YSQ== Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Lino Sanfilippo The following sequence of operations results in a refcount warning: 1. Open device /dev/tpmrm 2. Remove module tpm_tis_spi 3. Write a TPM command to the file descriptor opened at step 1. ------------[ cut here ]------------ WARNING: CPU: 3 PID: 1161 at lib/refcount.c:25 kobject_get+0xa0/0xa4 refcount_t: addition on 0; use-after-free. Modules linked in: tpm_tis_spi tpm_tis_core tpm mdio_bcm_unimac brcmfmac sha256_generic libsha256 sha256_arm hci_uart btbcm bluetooth cfg80211 vc4 brcmutil ecdh_generic ecc snd_soc_core crc32_arm_ce libaes raspberrypi_hwmon ac97_bus snd_pcm_dmaengine bcm2711_thermal snd_pcm snd_timer genet snd phy_generic soundcore [last unloaded: spi_bcm2835] CPU: 3 PID: 1161 Comm: hold_open Not tainted 5.10.0ls-main-dirty #2 Hardware name: BCM2711 [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0xc4/0xd8) [] (dump_stack) from [] (__warn+0x104/0x108) [] (__warn) from [] (warn_slowpath_fmt+0x74/0xb8) [] (warn_slowpath_fmt) from [] (kobject_get+0xa0/0xa4) [] (kobject_get) from [] (tpm_try_get_ops+0x14/0x54 [tpm]) [] (tpm_try_get_ops [tpm]) from [] (tpm_common_write+0x38/0x60 [tpm]) [] (tpm_common_write [tpm]) from [] (vfs_write+0xc4/0x3c0) [] (vfs_write) from [] (ksys_write+0x58/0xcc) [] (ksys_write) from [] (ret_fast_syscall+0x0/0x4c) Exception stack(0xc226bfa8 to 0xc226bff0) bfa0: 00000000 000105b4 00000003 beafe664 00000014 00000000 bfc0: 00000000 000105b4 000103f8 00000004 00000000 00000000 b6f9c000 beafe684 bfe0: 0000006c beafe648 0001056c b6eb6944 ---[ end trace d4b8409def9b8b1f ]--- The reason for this warning is the attempt to get the chip->dev reference in tpm_common_write() although the reference counter is already zero. Since commit 8979b02aaf1d ("tpm: Fix reference count to main device") the extra reference used to prevent a premature zero counter is never taken, because the required TPM_CHIP_FLAG_TPM2 flag is never set. Fix this by removing the flag condition. Commit fdc915f7f719 ("tpm: expose spaces via a device link /dev/tpmrm") already introduced function tpm_devs_release() to release the extra reference but did not implement the required put on chip->devs that results in the call of this function. Fix this also by installing an action handler that puts chip->devs as soon as the chip is unregistered. Fixes: fdc915f7f719 ("tpm: expose spaces via a device link /dev/tpmrm") Fixes: 8979b02aaf1d ("tpm: Fix reference count to main device") Signed-off-by: Lino Sanfilippo --- drivers/char/tpm/tpm-chip.c | 18 +++++++++++++++--- drivers/char/tpm/tpm_ftpm_tee.c | 2 ++ drivers/char/tpm/tpm_vtpm_proxy.c | 1 + 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index ddaeceb..3ace199 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -360,8 +360,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev, * while cdevs is in use. The corresponding put * is in the tpm_devs_release (TPM2 only) */ - if (chip->flags & TPM_CHIP_FLAG_TPM2) - get_device(&chip->dev); + get_device(&chip->dev); if (chip->dev_num == 0) chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR); @@ -422,8 +421,21 @@ struct tpm_chip *tpmm_chip_alloc(struct device *pdev, rc = devm_add_action_or_reset(pdev, (void (*)(void *)) put_device, &chip->dev); - if (rc) + if (rc) { + put_device(&chip->devs); return ERR_PTR(rc); + } + + rc = devm_add_action_or_reset(pdev, + (void (*)(void *)) put_device, + &chip->devs); + if (rc) { + devm_remove_action(pdev, + (void (*)(void *)) put_device, + &chip->dev); + put_device(&chip->dev); + return ERR_PTR(rc); + } dev_set_drvdata(pdev, chip); diff --git a/drivers/char/tpm/tpm_ftpm_tee.c b/drivers/char/tpm/tpm_ftpm_tee.c index 2ccdf8a..82858c2 100644 --- a/drivers/char/tpm/tpm_ftpm_tee.c +++ b/drivers/char/tpm/tpm_ftpm_tee.c @@ -286,6 +286,7 @@ static int ftpm_tee_probe(struct device *dev) out_chip: put_device(&pvt_data->chip->dev); + put_device(&pvt_data->chip->devs); out_chip_alloc: tee_shm_free(pvt_data->shm); out_shm_alloc: @@ -318,6 +319,7 @@ static int ftpm_tee_remove(struct device *dev) tpm_chip_unregister(pvt_data->chip); /* frees chip */ + put_device(&pvt_data->chip->devs); put_device(&pvt_data->chip->dev); /* Free the shared memory pool */ diff --git a/drivers/char/tpm/tpm_vtpm_proxy.c b/drivers/char/tpm/tpm_vtpm_proxy.c index 91c772e3..97b60f8 100644 --- a/drivers/char/tpm/tpm_vtpm_proxy.c +++ b/drivers/char/tpm/tpm_vtpm_proxy.c @@ -520,6 +520,7 @@ static struct proxy_dev *vtpm_proxy_create_proxy_dev(void) */ static inline void vtpm_proxy_delete_proxy_dev(struct proxy_dev *proxy_dev) { + put_device(&proxy_dev->chip->devs); put_device(&proxy_dev->chip->dev); /* frees chip */ kfree(proxy_dev); }