diff options
author | Kylene Jo Hall <kjhall@us.ibm.com> | 2006-01-08 04:03:48 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-08 23:14:00 -0500 |
commit | d09cf7d77f62f6fb2f6d63fe5980583805f2d559 (patch) | |
tree | 59192c9b47c424bdbc67606f6c2fc2214e7a37d2 /drivers/char/tpm | |
parent | 5e38291d80086f6972f471c7caffa03184de0bf0 (diff) |
[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: Kylene Jo Hall <kjhall@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char/tpm')
-rw-r--r-- | drivers/char/tpm/tpm_bios.c | 92 |
1 files changed, 62 insertions, 30 deletions
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index 5e1f4dfefa17..aedf7a8e6da7 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c | |||
@@ -29,6 +29,11 @@ | |||
29 | #define MAX_TEXT_EVENT 1000 /* Max event string length */ | 29 | #define MAX_TEXT_EVENT 1000 /* Max event string length */ |
30 | #define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ | 30 | #define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ |
31 | 31 | ||
32 | struct tpm_bios_log { | ||
33 | void *bios_event_log; | ||
34 | void *bios_event_log_end; | ||
35 | }; | ||
36 | |||
32 | struct acpi_tcpa { | 37 | struct acpi_tcpa { |
33 | struct acpi_table_header hdr; | 38 | struct acpi_table_header hdr; |
34 | u16 reserved; | 39 | u16 reserved; |
@@ -117,39 +122,34 @@ static const char* tcpa_pc_event_id_strings[] = { | |||
117 | "S-CRTM POST Contents", | 122 | "S-CRTM POST Contents", |
118 | }; | 123 | }; |
119 | 124 | ||
120 | /* (Binary) bios measurement buffer */ | ||
121 | static void *tcg_eventlog; | ||
122 | static void *tcg_eventlog_addr_limit; /* MAX */ | ||
123 | |||
124 | /* returns pointer to start of pos. entry of tcg log */ | 125 | /* returns pointer to start of pos. entry of tcg log */ |
125 | static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos) | 126 | static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos) |
126 | { | 127 | { |
127 | loff_t i; | 128 | loff_t i; |
128 | void *addr = tcg_eventlog; | 129 | struct tpm_bios_log *log = m->private; |
130 | void *addr = log->bios_event_log; | ||
131 | void *limit = log->bios_event_log_end; | ||
129 | struct tcpa_event *event; | 132 | struct tcpa_event *event; |
130 | 133 | ||
131 | /* read over *pos measurements */ | 134 | /* read over *pos measurements */ |
132 | for (i = 0; i < *pos; i++) { | 135 | for (i = 0; i < *pos; i++) { |
133 | event = addr; | 136 | event = addr; |
134 | 137 | ||
135 | if ((addr + sizeof(struct tcpa_event)) < | 138 | if ((addr + sizeof(struct tcpa_event)) < limit) { |
136 | tcg_eventlog_addr_limit) { | ||
137 | if (event->event_type == 0 && event->event_size == 0) | 139 | if (event->event_type == 0 && event->event_size == 0) |
138 | return NULL; | 140 | return NULL; |
139 | addr += | 141 | addr += sizeof(struct tcpa_event) + event->event_size; |
140 | sizeof(struct tcpa_event) + event->event_size; | ||
141 | } | 142 | } |
142 | } | 143 | } |
143 | 144 | ||
144 | /* now check if current entry is valid */ | 145 | /* now check if current entry is valid */ |
145 | if ((addr + sizeof(struct tcpa_event)) >= tcg_eventlog_addr_limit) | 146 | if ((addr + sizeof(struct tcpa_event)) >= limit) |
146 | return NULL; | 147 | return NULL; |
147 | 148 | ||
148 | event = addr; | 149 | event = addr; |
149 | 150 | ||
150 | if ((event->event_type == 0 && event->event_size == 0) || | 151 | if ((event->event_type == 0 && event->event_size == 0) || |
151 | ((addr + sizeof(struct tcpa_event) + event->event_size) >= | 152 | ((addr + sizeof(struct tcpa_event) + event->event_size) >= limit)) |
152 | tcg_eventlog_addr_limit)) | ||
153 | return NULL; | 153 | return NULL; |
154 | 154 | ||
155 | return addr; | 155 | return addr; |
@@ -159,11 +159,13 @@ static void *tpm_bios_measurements_next(struct seq_file *m, void *v, | |||
159 | loff_t *pos) | 159 | loff_t *pos) |
160 | { | 160 | { |
161 | struct tcpa_event *event = v; | 161 | struct tcpa_event *event = v; |
162 | struct tpm_bios_log *log = m->private; | ||
163 | void *limit = log->bios_event_log_end; | ||
162 | 164 | ||
163 | v += sizeof(struct tcpa_event) + event->event_size; | 165 | v += sizeof(struct tcpa_event) + event->event_size; |
164 | 166 | ||
165 | /* now check if current entry is valid */ | 167 | /* now check if current entry is valid */ |
166 | if ((v + sizeof(struct tcpa_event)) >= tcg_eventlog_addr_limit) | 168 | if ((v + sizeof(struct tcpa_event)) >= limit) |
167 | return NULL; | 169 | return NULL; |
168 | 170 | ||
169 | event = v; | 171 | event = v; |
@@ -172,8 +174,7 @@ static void *tpm_bios_measurements_next(struct seq_file *m, void *v, | |||
172 | return NULL; | 174 | return NULL; |
173 | 175 | ||
174 | if ((event->event_type == 0 && event->event_size == 0) || | 176 | if ((event->event_type == 0 && event->event_size == 0) || |
175 | ((v + sizeof(struct tcpa_event) + event->event_size) >= | 177 | ((v + sizeof(struct tcpa_event) + event->event_size) >= limit)) |
176 | tcg_eventlog_addr_limit)) | ||
177 | return NULL; | 178 | return NULL; |
178 | 179 | ||
179 | (*pos)++; | 180 | (*pos)++; |
@@ -312,10 +313,14 @@ static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v) | |||
312 | static int tpm_bios_measurements_release(struct inode *inode, | 313 | static int tpm_bios_measurements_release(struct inode *inode, |
313 | struct file *file) | 314 | struct file *file) |
314 | { | 315 | { |
315 | if (tcg_eventlog) { | 316 | struct seq_file *seq = file->private_data; |
316 | kfree(tcg_eventlog); | 317 | struct tpm_bios_log *log = seq->private; |
317 | tcg_eventlog = NULL; | 318 | |
319 | if (log) { | ||
320 | kfree(log->bios_event_log); | ||
321 | kfree(log); | ||
318 | } | 322 | } |
323 | |||
319 | return seq_release(inode, file); | 324 | return seq_release(inode, file); |
320 | } | 325 | } |
321 | 326 | ||
@@ -367,13 +372,13 @@ static struct seq_operations tpm_binary_b_measurments_seqops = { | |||
367 | }; | 372 | }; |
368 | 373 | ||
369 | /* read binary bios log */ | 374 | /* read binary bios log */ |
370 | static int read_log(void) | 375 | static int read_log(struct tpm_bios_log *log) |
371 | { | 376 | { |
372 | struct acpi_tcpa *buff; | 377 | struct acpi_tcpa *buff; |
373 | acpi_status status; | 378 | acpi_status status; |
374 | void *virt; | 379 | void *virt; |
375 | 380 | ||
376 | if (tcg_eventlog != NULL) { | 381 | if (log->bios_event_log != NULL) { |
377 | printk(KERN_ERR | 382 | printk(KERN_ERR |
378 | "%s: ERROR - Eventlog already initialized\n", | 383 | "%s: ERROR - Eventlog already initialized\n", |
379 | __func__); | 384 | __func__); |
@@ -393,25 +398,24 @@ static int read_log(void) | |||
393 | } | 398 | } |
394 | 399 | ||
395 | if (buff->log_max_len == 0) { | 400 | if (buff->log_max_len == 0) { |
396 | printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", | 401 | printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__); |
397 | __func__); | ||
398 | return -EIO; | 402 | return -EIO; |
399 | } | 403 | } |
400 | 404 | ||
401 | /* malloc EventLog space */ | 405 | /* malloc EventLog space */ |
402 | tcg_eventlog = kmalloc(buff->log_max_len, GFP_KERNEL); | 406 | log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL); |
403 | if (!tcg_eventlog) { | 407 | if (!log->bios_event_log) { |
404 | printk | 408 | printk |
405 | ("%s: ERROR - Not enough Memory for BIOS measurements\n", | 409 | ("%s: ERROR - Not enough Memory for BIOS measurements\n", |
406 | __func__); | 410 | __func__); |
407 | return -ENOMEM; | 411 | return -ENOMEM; |
408 | } | 412 | } |
409 | 413 | ||
410 | tcg_eventlog_addr_limit = tcg_eventlog + buff->log_max_len; | 414 | log->bios_event_log_end = log->bios_event_log + buff->log_max_len; |
411 | 415 | ||
412 | acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, &virt); | 416 | acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, &virt); |
413 | 417 | ||
414 | memcpy(tcg_eventlog, virt, buff->log_max_len); | 418 | memcpy(log->bios_event_log, virt, buff->log_max_len); |
415 | 419 | ||
416 | acpi_os_unmap_memory(virt, buff->log_max_len); | 420 | acpi_os_unmap_memory(virt, buff->log_max_len); |
417 | return 0; | 421 | return 0; |
@@ -421,12 +425,26 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode, | |||
421 | struct file *file) | 425 | struct file *file) |
422 | { | 426 | { |
423 | int err; | 427 | int err; |
428 | struct tpm_bios_log *log; | ||
429 | struct seq_file *seq; | ||
424 | 430 | ||
425 | if ((err = read_log())) | 431 | log = kzalloc(sizeof(struct tpm_bios_log), GFP_KERNEL); |
432 | if (!log) | ||
433 | return -ENOMEM; | ||
434 | |||
435 | if ((err = read_log(log))) | ||
426 | return err; | 436 | return err; |
427 | 437 | ||
428 | /* now register seq file */ | 438 | /* now register seq file */ |
429 | return seq_open(file, &tpm_ascii_b_measurments_seqops); | 439 | err = seq_open(file, &tpm_ascii_b_measurments_seqops); |
440 | if (!err) { | ||
441 | seq = file->private_data; | ||
442 | seq->private = log; | ||
443 | } else { | ||
444 | kfree(log->bios_event_log); | ||
445 | kfree(log); | ||
446 | } | ||
447 | return err; | ||
430 | } | 448 | } |
431 | 449 | ||
432 | struct file_operations tpm_ascii_bios_measurements_ops = { | 450 | struct file_operations tpm_ascii_bios_measurements_ops = { |
@@ -440,12 +458,26 @@ static int tpm_binary_bios_measurements_open(struct inode *inode, | |||
440 | struct file *file) | 458 | struct file *file) |
441 | { | 459 | { |
442 | int err; | 460 | int err; |
461 | struct tpm_bios_log *log; | ||
462 | struct seq_file *seq; | ||
443 | 463 | ||
444 | if ((err = read_log())) | 464 | log = kzalloc(sizeof(struct tpm_bios_log), GFP_KERNEL); |
465 | if (!log) | ||
466 | return -ENOMEM; | ||
467 | |||
468 | if ((err = read_log(log))) | ||
445 | return err; | 469 | return err; |
446 | 470 | ||
447 | /* now register seq file */ | 471 | /* now register seq file */ |
448 | return seq_open(file, &tpm_binary_b_measurments_seqops); | 472 | err = seq_open(file, &tpm_binary_b_measurments_seqops); |
473 | if (!err) { | ||
474 | seq = file->private_data; | ||
475 | seq->private = log; | ||
476 | } else { | ||
477 | kfree(log->bios_event_log); | ||
478 | kfree(log); | ||
479 | } | ||
480 | return err; | ||
449 | } | 481 | } |
450 | 482 | ||
451 | struct file_operations tpm_binary_bios_measurements_ops = { | 483 | struct file_operations tpm_binary_bios_measurements_ops = { |