Skip to content

Commit 877063f

Browse files
vwaxintel-lab-lkp
authored andcommitted
tpm: Fix tpmrm reference counting
The code added by commit 8979b02 ("tpm: Fix reference count to main device") tries to take an extra reference to the main device only for TPM2 by looking at the flags, but the flags are actually not set at the time when tpm_chip_alloc() is called, so no extra reference is ever taken, leading to a use-after-free if the TPM modules are removed when the tpmrm device is in use. ================================================================== BUG: KASAN: use-after-free in __mutex_lock+0xe0/0xbd0 Read of size 8 at addr ffff888116c6acc0 by task sh/1210 CPU: 0 PID: 1210 Comm: sh Not tainted 5.13.0-rc5+ torvalds#200 Call Trace: __mutex_lock+0xe0/0xbd0 tpm2_del_space+0x24/0xa0 [tpm] tpmrm_release+0x3f/0x50 [tpm] __fput+0x110/0x3c0 task_work_run+0x94/0xd0 do_exit+0x683/0x13e0 do_syscall_64+0x3c/0x80 Allocated by task 1153: kasan_save_stack+0x19/0x40 __kasan_kmalloc+0x7f/0xa0 tpm_chip_alloc+0x3b/0x360 [tpm] tpmm_chip_alloc+0x11/0x70 [tpm] tpm_tis_core_init+0xce/0x570 [tpm_tis_core] pnp_device_probe+0x9c/0x100 ... Freed by task 1243: kfree+0x121/0x340 device_release+0x59/0xf0 kobject_put+0xa5/0x120 release_nodes+0x37f/0x3f0 driver_detach+0x7c/0xf0 bus_remove_driver+0x86/0x110 __x64_sys_delete_module+0x27b/0x320 ... ================================================================== The real fix to the problem which that commit tried to solve is to make tpmm_chip_alloc() put the ->devs device in the devm release function, since that is never done anywhere currently. This is safe since device_initialize() is always called on ->devs. No conditional reference taking is needed. Fixes: 8979b02 ("tpm: Fix reference count to main device") Signed-off-by: Vincent Whitchurch <[email protected]>
1 parent 60f86b9 commit 877063f

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

drivers/char/tpm/tpm-chip.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -358,10 +358,9 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
358358
/* get extra reference on main device to hold on
359359
* behalf of devs. This holds the chip structure
360360
* while cdevs is in use. The corresponding put
361-
* is in the tpm_devs_release (TPM2 only)
361+
* is in the tpm_devs_release
362362
*/
363-
if (chip->flags & TPM_CHIP_FLAG_TPM2)
364-
get_device(&chip->dev);
363+
get_device(&chip->dev);
365364

366365
if (chip->dev_num == 0)
367366
chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);
@@ -402,6 +401,14 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
402401
}
403402
EXPORT_SYMBOL_GPL(tpm_chip_alloc);
404403

404+
static void tpmm_chip_release(void *data)
405+
{
406+
struct tpm_chip *chip = data;
407+
408+
put_device(&chip->devs);
409+
put_device(&chip->dev);
410+
}
411+
405412
/**
406413
* tpmm_chip_alloc() - allocate a new struct tpm_chip instance
407414
* @pdev: parent device to which the chip is associated
@@ -419,9 +426,7 @@ struct tpm_chip *tpmm_chip_alloc(struct device *pdev,
419426
if (IS_ERR(chip))
420427
return chip;
421428

422-
rc = devm_add_action_or_reset(pdev,
423-
(void (*)(void *)) put_device,
424-
&chip->dev);
429+
rc = devm_add_action_or_reset(pdev, tpmm_chip_release, chip);
425430
if (rc)
426431
return ERR_PTR(rc);
427432

0 commit comments

Comments
 (0)