File Index
Files and directories
Sign in
FILE

common.c

File preview with syntax highlighting.

linux-6.19.14/drivers/char/tpm/eventlog/common.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Copyright (C) 2005, 2012 IBM Corporation
  4 *
  5 * Authors:
  6 *	Kent Yoder <key@linux.vnet.ibm.com>
  7 *	Seiji Munetoh <munetoh@jp.ibm.com>
  8 *	Stefan Berger <stefanb@us.ibm.com>
  9 *	Reiner Sailer <sailer@watson.ibm.com>
 10 *	Kylene Hall <kjhall@us.ibm.com>
 11 *	Nayna Jain <nayna@linux.vnet.ibm.com>
 12 *
 13 * Access to the event log created by a system's firmware / BIOS
 14 */
 15
 16#include <linux/seq_file.h>
 17#include <linux/fs.h>
 18#include <linux/security.h>
 19#include <linux/module.h>
 20#include <linux/tpm_eventlog.h>
 21
 22#include "../tpm.h"
 23#include "common.h"
 24
 25static int tpm_bios_measurements_open(struct inode *inode,
 26					    struct file *file)
 27{
 28	int err;
 29	struct seq_file *seq;
 30	struct tpm_chip_seqops *chip_seqops;
 31	const struct seq_operations *seqops;
 32	struct tpm_chip *chip;
 33
 34	inode_lock(inode);
 35	if (!inode->i_nlink) {
 36		inode_unlock(inode);
 37		return -ENODEV;
 38	}
 39	chip_seqops = inode->i_private;
 40	seqops = chip_seqops->seqops;
 41	chip = chip_seqops->chip;
 42	get_device(&chip->dev);
 43	inode_unlock(inode);
 44
 45	/* now register seq file */
 46	err = seq_open(file, seqops);
 47	if (!err) {
 48		seq = file->private_data;
 49		seq->private = chip;
 50	} else {
 51		put_device(&chip->dev);
 52	}
 53
 54	return err;
 55}
 56
 57static int tpm_bios_measurements_release(struct inode *inode,
 58					 struct file *file)
 59{
 60	struct seq_file *seq = file->private_data;
 61	struct tpm_chip *chip = seq->private;
 62
 63	put_device(&chip->dev);
 64
 65	return seq_release(inode, file);
 66}
 67
 68static const struct file_operations tpm_bios_measurements_ops = {
 69	.owner = THIS_MODULE,
 70	.open = tpm_bios_measurements_open,
 71	.read = seq_read,
 72	.llseek = seq_lseek,
 73	.release = tpm_bios_measurements_release,
 74};
 75
 76static int tpm_read_log(struct tpm_chip *chip)
 77{
 78	int rc;
 79
 80	if (chip->log.bios_event_log != NULL) {
 81		dev_dbg(&chip->dev,
 82			"%s: ERROR - event log already initialized\n",
 83			__func__);
 84		return -EFAULT;
 85	}
 86
 87	rc = tpm_read_log_acpi(chip);
 88	if (rc != -ENODEV)
 89		return rc;
 90
 91	rc = tpm_read_log_efi(chip);
 92	if (rc != -ENODEV)
 93		return rc;
 94
 95	return tpm_read_log_of(chip);
 96}
 97
 98/*
 99 * tpm_bios_log_setup() - Read the event log from the firmware
100 * @chip: TPM chip to use.
101 *
102 * If an event log is found then the securityfs files are setup to
103 * export it to userspace, otherwise nothing is done.
104 */
105void tpm_bios_log_setup(struct tpm_chip *chip)
106{
107	const char *name = dev_name(&chip->dev);
108	struct dentry *dentry;
109	int log_version;
110	int rc = 0;
111
112	if (chip->flags & TPM_CHIP_FLAG_VIRTUAL)
113		return;
114
115	rc = tpm_read_log(chip);
116	if (rc < 0)
117		return;
118	log_version = rc;
119
120	chip->bios_dir = securityfs_create_dir(name, NULL);
121	/* NOTE: securityfs_create_dir can return ENODEV if securityfs is
122	 * compiled out. The caller should ignore the ENODEV return code.
123	 */
124	if (IS_ERR(chip->bios_dir))
125		return;
126
127	chip->bin_log_seqops.chip = chip;
128	if (log_version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
129		chip->bin_log_seqops.seqops =
130			&tpm2_binary_b_measurements_seqops;
131	else
132		chip->bin_log_seqops.seqops =
133			&tpm1_binary_b_measurements_seqops;
134
135
136	dentry =
137	    securityfs_create_file("binary_bios_measurements",
138				   0440, chip->bios_dir,
139				   (void *)&chip->bin_log_seqops,
140				   &tpm_bios_measurements_ops);
141	if (IS_ERR(dentry))
142		goto err;
143
144	if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
145
146		chip->ascii_log_seqops.chip = chip;
147		chip->ascii_log_seqops.seqops =
148			&tpm1_ascii_b_measurements_seqops;
149
150		dentry =
151			securityfs_create_file("ascii_bios_measurements",
152					       0440, chip->bios_dir,
153					       (void *)&chip->ascii_log_seqops,
154					       &tpm_bios_measurements_ops);
155		if (IS_ERR(dentry))
156			goto err;
157	}
158
159	return;
160
161err:
162	tpm_bios_log_teardown(chip);
163	return;
164}
165
166void tpm_bios_log_teardown(struct tpm_chip *chip)
167{
168	securityfs_remove(chip->bios_dir);
169}
~/ Read-only file preview.