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

[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
...@@ -29,6 +29,11 @@ ...@@ -29,6 +29,11 @@
#define MAX_TEXT_EVENT 1000 /* Max event string length */ #define MAX_TEXT_EVENT 1000 /* Max event string length */
#define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ #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_tcpa {
struct acpi_table_header hdr; struct acpi_table_header hdr;
u16 reserved; u16 reserved;
...@@ -117,39 +122,34 @@ static const char* tcpa_pc_event_id_strings[] = { ...@@ -117,39 +122,34 @@ static const char* tcpa_pc_event_id_strings[] = {
"S-CRTM POST Contents", "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 */ /* returns pointer to start of pos. entry of tcg log */
static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos) static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos)
{ {
loff_t i; 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; struct tcpa_event *event;
/* read over *pos measurements */ /* read over *pos measurements */
for (i = 0; i < *pos; i++) { for (i = 0; i < *pos; i++) {
event = addr; event = addr;
if ((addr + sizeof(struct tcpa_event)) < if ((addr + sizeof(struct tcpa_event)) < limit) {
tcg_eventlog_addr_limit) {
if (event->event_type == 0 && event->event_size == 0) if (event->event_type == 0 && event->event_size == 0)
return NULL; return NULL;
addr += addr += sizeof(struct tcpa_event) + event->event_size;
sizeof(struct tcpa_event) + event->event_size;
} }
} }
/* now check if current entry is valid */ /* 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; return NULL;
event = addr; event = addr;
if ((event->event_type == 0 && event->event_size == 0) || if ((event->event_type == 0 && event->event_size == 0) ||
((addr + sizeof(struct tcpa_event) + event->event_size) >= ((addr + sizeof(struct tcpa_event) + event->event_size) >= limit))
tcg_eventlog_addr_limit))
return NULL; return NULL;
return addr; return addr;
...@@ -159,11 +159,13 @@ static void *tpm_bios_measurements_next(struct seq_file *m, void *v, ...@@ -159,11 +159,13 @@ static void *tpm_bios_measurements_next(struct seq_file *m, void *v,
loff_t *pos) loff_t *pos)
{ {
struct tcpa_event *event = v; 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; v += sizeof(struct tcpa_event) + event->event_size;
/* now check if current entry is valid */ /* 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; return NULL;
event = v; event = v;
...@@ -172,8 +174,7 @@ static void *tpm_bios_measurements_next(struct seq_file *m, void *v, ...@@ -172,8 +174,7 @@ static void *tpm_bios_measurements_next(struct seq_file *m, void *v,
return NULL; return NULL;
if ((event->event_type == 0 && event->event_size == 0) || if ((event->event_type == 0 && event->event_size == 0) ||
((v + sizeof(struct tcpa_event) + event->event_size) >= ((v + sizeof(struct tcpa_event) + event->event_size) >= limit))
tcg_eventlog_addr_limit))
return NULL; return NULL;
(*pos)++; (*pos)++;
...@@ -312,10 +313,14 @@ static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v) ...@@ -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, static int tpm_bios_measurements_release(struct inode *inode,
struct file *file) struct file *file)
{ {
if (tcg_eventlog) { struct seq_file *seq = file->private_data;
kfree(tcg_eventlog); struct tpm_bios_log *log = seq->private;
tcg_eventlog = NULL;
if (log) {
kfree(log->bios_event_log);
kfree(log);
} }
return seq_release(inode, file); return seq_release(inode, file);
} }
...@@ -367,13 +372,13 @@ static struct seq_operations tpm_binary_b_measurments_seqops = { ...@@ -367,13 +372,13 @@ static struct seq_operations tpm_binary_b_measurments_seqops = {
}; };
/* read binary bios log */ /* read binary bios log */
static int read_log(void) static int read_log(struct tpm_bios_log *log)
{ {
struct acpi_tcpa *buff; struct acpi_tcpa *buff;
acpi_status status; acpi_status status;
void *virt; void *virt;
if (tcg_eventlog != NULL) { if (log->bios_event_log != NULL) {
printk(KERN_ERR printk(KERN_ERR
"%s: ERROR - Eventlog already initialized\n", "%s: ERROR - Eventlog already initialized\n",
__func__); __func__);
...@@ -393,25 +398,24 @@ static int read_log(void) ...@@ -393,25 +398,24 @@ static int read_log(void)
} }
if (buff->log_max_len == 0) { if (buff->log_max_len == 0) {
printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
__func__);
return -EIO; return -EIO;
} }
/* malloc EventLog space */ /* malloc EventLog space */
tcg_eventlog = kmalloc(buff->log_max_len, GFP_KERNEL); log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL);
if (!tcg_eventlog) { if (!log->bios_event_log) {
printk printk
("%s: ERROR - Not enough Memory for BIOS measurements\n", ("%s: ERROR - Not enough Memory for BIOS measurements\n",
__func__); __func__);
return -ENOMEM; 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); 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); acpi_os_unmap_memory(virt, buff->log_max_len);
return 0; return 0;
...@@ -421,12 +425,26 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode, ...@@ -421,12 +425,26 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode,
struct file *file) struct file *file)
{ {
int err; 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; return err;
/* now register seq file */ /* 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 = { struct file_operations tpm_ascii_bios_measurements_ops = {
...@@ -440,12 +458,26 @@ static int tpm_binary_bios_measurements_open(struct inode *inode, ...@@ -440,12 +458,26 @@ static int tpm_binary_bios_measurements_open(struct inode *inode,
struct file *file) struct file *file)
{ {
int err; 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; return err;
/* now register seq file */ /* 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 = { struct file_operations tpm_binary_bios_measurements_ops = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment