]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
tpm: don't bother with removal of files in directory we'll be removing
authorAl Viro <viro@zeniv.linux.org.uk>
Wed, 11 Jun 2025 23:40:04 +0000 (19:40 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 17 Jun 2025 22:11:01 +0000 (18:11 -0400)
FWIW, there is a reliable indication of removal - ->i_nlink going to 0 ;-)

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
drivers/char/tpm/eventlog/common.c
include/linux/tpm.h

index 4c0bbba64ee500f9fa3c3feab2f4cdffbf49563c..691813d2a5a2aaef01cbe353fea5ccb8b7edeebe 100644 (file)
@@ -32,7 +32,7 @@ static int tpm_bios_measurements_open(struct inode *inode,
        struct tpm_chip *chip;
 
        inode_lock(inode);
-       if (!inode->i_private) {
+       if (!inode->i_nlink) {
                inode_unlock(inode);
                return -ENODEV;
        }
@@ -105,7 +105,7 @@ static int tpm_read_log(struct tpm_chip *chip)
 void tpm_bios_log_setup(struct tpm_chip *chip)
 {
        const char *name = dev_name(&chip->dev);
-       unsigned int cnt;
+       struct dentry *dentry;
        int log_version;
        int rc = 0;
 
@@ -117,14 +117,12 @@ void tpm_bios_log_setup(struct tpm_chip *chip)
                return;
        log_version = rc;
 
-       cnt = 0;
-       chip->bios_dir[cnt] = securityfs_create_dir(name, NULL);
+       chip->bios_dir = securityfs_create_dir(name, NULL);
        /* NOTE: securityfs_create_dir can return ENODEV if securityfs is
         * compiled out. The caller should ignore the ENODEV return code.
         */
-       if (IS_ERR(chip->bios_dir[cnt]))
-               goto err;
-       cnt++;
+       if (IS_ERR(chip->bios_dir))
+               return;
 
        chip->bin_log_seqops.chip = chip;
        if (log_version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
@@ -135,14 +133,13 @@ void tpm_bios_log_setup(struct tpm_chip *chip)
                        &tpm1_binary_b_measurements_seqops;
 
 
-       chip->bios_dir[cnt] =
+       dentry =
            securityfs_create_file("binary_bios_measurements",
-                                  0440, chip->bios_dir[0],
+                                  0440, chip->bios_dir,
                                   (void *)&chip->bin_log_seqops,
                                   &tpm_bios_measurements_ops);
-       if (IS_ERR(chip->bios_dir[cnt]))
+       if (IS_ERR(dentry))
                goto err;
-       cnt++;
 
        if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
 
@@ -150,42 +147,23 @@ void tpm_bios_log_setup(struct tpm_chip *chip)
                chip->ascii_log_seqops.seqops =
                        &tpm1_ascii_b_measurements_seqops;
 
-               chip->bios_dir[cnt] =
+               dentry =
                        securityfs_create_file("ascii_bios_measurements",
-                                              0440, chip->bios_dir[0],
+                                              0440, chip->bios_dir,
                                               (void *)&chip->ascii_log_seqops,
                                               &tpm_bios_measurements_ops);
-               if (IS_ERR(chip->bios_dir[cnt]))
+               if (IS_ERR(dentry))
                        goto err;
-               cnt++;
        }
 
        return;
 
 err:
-       chip->bios_dir[cnt] = NULL;
        tpm_bios_log_teardown(chip);
        return;
 }
 
 void tpm_bios_log_teardown(struct tpm_chip *chip)
 {
-       int i;
-       struct inode *inode;
-
-       /* securityfs_remove currently doesn't take care of handling sync
-        * between removal and opening of pseudo files. To handle this, a
-        * workaround is added by making i_private = NULL here during removal
-        * and to check it during open(), both within inode_lock()/unlock().
-        * This design ensures that open() either safely gets kref or fails.
-        */
-       for (i = (TPM_NUM_EVENT_LOG_FILES - 1); i >= 0; i--) {
-               if (chip->bios_dir[i]) {
-                       inode = d_inode(chip->bios_dir[i]);
-                       inode_lock(inode);
-                       inode->i_private = NULL;
-                       inode_unlock(inode);
-                       securityfs_remove(chip->bios_dir[i]);
-               }
-       }
+       securityfs_remove(chip->bios_dir);
 }
index a3d8305e88a51ec41c3fe1286c3b54f360d281db..9894c104dc937fe4e0b11f5f144e0c3ce48dd354 100644 (file)
@@ -182,7 +182,7 @@ struct tpm_chip {
        unsigned long duration[TPM_NUM_DURATIONS]; /* jiffies */
        bool duration_adjusted;
 
-       struct dentry *bios_dir[TPM_NUM_EVENT_LOG_FILES];
+       struct dentry *bios_dir;
 
        const struct attribute_group *groups[3 + TPM_MAX_HASHES];
        unsigned int groups_cnt;