Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d09cf7d7 authored by Kylene Jo Hall's avatar Kylene Jo Hall Committed by Linus Torvalds
Browse files

[PATCH] tpmdd: remove global event log



Remove global event log in the tpm bios event measurement log code that
would have caused problems when the code was run concurrently.  A log is
now allocated and attached to the seq file upon open and destroyed
appropriately.

Signed-off-by: default avatarKylene Jo Hall <kjhall@us.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 5e38291d
Loading
Loading
Loading
Loading
+62 −30
Original line number Diff line number Diff line
@@ -29,6 +29,11 @@
#define MAX_TEXT_EVENT		1000	/* Max event string length */
#define ACPI_TCPA_SIG		"TCPA"	/* 0x41504354 /'TCPA' */

struct tpm_bios_log {
	void *bios_event_log;
	void *bios_event_log_end;
};

struct acpi_tcpa {
	struct acpi_table_header hdr;
	u16 reserved;
@@ -117,39 +122,34 @@ static const char* tcpa_pc_event_id_strings[] = {
	"S-CRTM POST Contents",
};

/* (Binary) bios measurement buffer */
static void *tcg_eventlog;
static void *tcg_eventlog_addr_limit;	/* MAX */

/* returns pointer to start of pos. entry of tcg log */
static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos)
{
	loff_t i;
	void *addr = tcg_eventlog;
	struct tpm_bios_log *log = m->private;
	void *addr = log->bios_event_log;
	void *limit = log->bios_event_log_end;
	struct tcpa_event *event;

	/* read over *pos measurements */
	for (i = 0; i < *pos; i++) {
		event = addr;

		if ((addr + sizeof(struct tcpa_event)) <
		    tcg_eventlog_addr_limit) {
		if ((addr + sizeof(struct tcpa_event)) < limit) {
			if (event->event_type == 0 && event->event_size == 0)
				return NULL;
			addr +=
			    sizeof(struct tcpa_event) + event->event_size;
			addr += sizeof(struct tcpa_event) + event->event_size;
		}
	}

	/* now check if current entry is valid */
	if ((addr + sizeof(struct tcpa_event)) >= tcg_eventlog_addr_limit)
	if ((addr + sizeof(struct tcpa_event)) >= limit)
		return NULL;

	event = addr;

	if ((event->event_type == 0 && event->event_size == 0) ||
	    ((addr + sizeof(struct tcpa_event) + event->event_size) >=
	     tcg_eventlog_addr_limit))
	    ((addr + sizeof(struct tcpa_event) + event->event_size) >= limit))
		return NULL;

	return addr;
@@ -159,11 +159,13 @@ static void *tpm_bios_measurements_next(struct seq_file *m, void *v,
					loff_t *pos)
{
	struct tcpa_event *event = v;
	struct tpm_bios_log *log = m->private;
	void *limit = log->bios_event_log_end;

	v += sizeof(struct tcpa_event) + event->event_size;

	/* now check if current entry is valid */
	if ((v + sizeof(struct tcpa_event)) >= tcg_eventlog_addr_limit)
	if ((v + sizeof(struct tcpa_event)) >= limit)
		return NULL;

	event = v;
@@ -172,8 +174,7 @@ static void *tpm_bios_measurements_next(struct seq_file *m, void *v,
		return NULL;

	if ((event->event_type == 0 && event->event_size == 0) ||
	    ((v + sizeof(struct tcpa_event) + event->event_size) >=
	     tcg_eventlog_addr_limit))
	    ((v + sizeof(struct tcpa_event) + event->event_size) >= limit))
		return NULL;

	(*pos)++;
@@ -312,10 +313,14 @@ static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
static int tpm_bios_measurements_release(struct inode *inode,
					 struct file *file)
{
	if (tcg_eventlog) {
		kfree(tcg_eventlog);
		tcg_eventlog = NULL;
	struct seq_file *seq = file->private_data;
	struct tpm_bios_log *log = seq->private;

	if (log) {
		kfree(log->bios_event_log);
		kfree(log);
	}

	return seq_release(inode, file);
}

@@ -367,13 +372,13 @@ static struct seq_operations tpm_binary_b_measurments_seqops = {
};

/* read binary bios log */
static int read_log(void)
static int read_log(struct tpm_bios_log *log)
{
	struct acpi_tcpa *buff;
	acpi_status status;
	void *virt;

	if (tcg_eventlog != NULL) {
	if (log->bios_event_log != NULL) {
		printk(KERN_ERR
		       "%s: ERROR - Eventlog already initialized\n",
		       __func__);
@@ -393,25 +398,24 @@ static int read_log(void)
	}

	if (buff->log_max_len == 0) {
		printk(KERN_ERR "%s: ERROR - TCPA log area empty\n",
		       __func__);
		printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
		return -EIO;
	}

	/* malloc EventLog space */
	tcg_eventlog = kmalloc(buff->log_max_len, GFP_KERNEL);
	if (!tcg_eventlog) {
	log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL);
	if (!log->bios_event_log) {
		printk
		    ("%s: ERROR - Not enough  Memory for BIOS measurements\n",
		     __func__);
		return -ENOMEM;
	}

	tcg_eventlog_addr_limit = tcg_eventlog + buff->log_max_len;
	log->bios_event_log_end = log->bios_event_log + buff->log_max_len;

	acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, &virt);

	memcpy(tcg_eventlog, virt, buff->log_max_len);
	memcpy(log->bios_event_log, virt, buff->log_max_len);

	acpi_os_unmap_memory(virt, buff->log_max_len);
	return 0;
@@ -421,12 +425,26 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode,
					    struct file *file)
{
	int err;
	struct tpm_bios_log *log;
	struct seq_file *seq;

	log = kzalloc(sizeof(struct tpm_bios_log), GFP_KERNEL);
	if (!log)
		return -ENOMEM;

	if ((err = read_log()))
	if ((err = read_log(log)))
		return err;

	/* now register seq file */
	return seq_open(file, &tpm_ascii_b_measurments_seqops);
	err = seq_open(file, &tpm_ascii_b_measurments_seqops);
	if (!err) {
		seq = file->private_data;
		seq->private = log;
	} else {
		kfree(log->bios_event_log);
		kfree(log);
	}
	return err;
}

struct file_operations tpm_ascii_bios_measurements_ops = {
@@ -440,12 +458,26 @@ static int tpm_binary_bios_measurements_open(struct inode *inode,
					     struct file *file)
{
	int err;
	struct tpm_bios_log *log;
	struct seq_file *seq;

	if ((err = read_log()))
	log = kzalloc(sizeof(struct tpm_bios_log), GFP_KERNEL);
	if (!log)
		return -ENOMEM;

	if ((err = read_log(log)))
		return err;

	/* now register seq file */
	return seq_open(file, &tpm_binary_b_measurments_seqops);
	err = seq_open(file, &tpm_binary_b_measurments_seqops);
	if (!err) {
		seq = file->private_data;
		seq->private = log;
	} else {
		kfree(log->bios_event_log);
		kfree(log);
	}
	return err;
}

struct file_operations tpm_binary_bios_measurements_ops = {