Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Kylene Jo Hall and committed by
Linus Torvalds
d09cf7d7 5e38291d

+62 -30
+62 -30
drivers/char/tpm/tpm_bios.c
··· 29 29 #define MAX_TEXT_EVENT 1000 /* Max event string length */ 30 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 37 struct acpi_tcpa { 33 38 struct acpi_table_header hdr; 34 39 u16 reserved; ··· 122 117 "S-CRTM POST Contents", 123 118 }; 124 119 125 - /* (Binary) bios measurement buffer */ 126 - static void *tcg_eventlog; 127 - static void *tcg_eventlog_addr_limit; /* MAX */ 128 - 129 120 /* returns pointer to start of pos. entry of tcg log */ 130 121 static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos) 131 122 { 132 123 loff_t i; 133 - void *addr = tcg_eventlog; 124 + struct tpm_bios_log *log = m->private; 125 + void *addr = log->bios_event_log; 126 + void *limit = log->bios_event_log_end; 134 127 struct tcpa_event *event; 135 128 136 129 /* read over *pos measurements */ 137 130 for (i = 0; i < *pos; i++) { 138 131 event = addr; 139 132 140 - if ((addr + sizeof(struct tcpa_event)) < 141 - tcg_eventlog_addr_limit) { 133 + if ((addr + sizeof(struct tcpa_event)) < limit) { 142 134 if (event->event_type == 0 && event->event_size == 0) 143 135 return NULL; 144 - addr += 145 - sizeof(struct tcpa_event) + event->event_size; 136 + addr += sizeof(struct tcpa_event) + event->event_size; 146 137 } 147 138 } 148 139 149 140 /* now check if current entry is valid */ 150 - if ((addr + sizeof(struct tcpa_event)) >= tcg_eventlog_addr_limit) 141 + if ((addr + sizeof(struct tcpa_event)) >= limit) 151 142 return NULL; 152 143 153 144 event = addr; 154 145 155 146 if ((event->event_type == 0 && event->event_size == 0) || 156 - ((addr + sizeof(struct tcpa_event) + event->event_size) >= 157 - tcg_eventlog_addr_limit)) 147 + ((addr + sizeof(struct tcpa_event) + event->event_size) >= limit)) 158 148 return NULL; 159 149 160 150 return addr; ··· 159 159 loff_t *pos) 160 160 { 161 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 165 v += sizeof(struct tcpa_event) + event->event_size; 164 166 165 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 169 return NULL; 168 170 169 171 event = v; ··· 174 172 return NULL; 175 173 176 174 if ((event->event_type == 0 && event->event_size == 0) || 177 - ((v + sizeof(struct tcpa_event) + event->event_size) >= 178 - tcg_eventlog_addr_limit)) 175 + ((v + sizeof(struct tcpa_event) + event->event_size) >= limit)) 179 176 return NULL; 180 177 181 178 (*pos)++; ··· 313 312 static int tpm_bios_measurements_release(struct inode *inode, 314 313 struct file *file) 315 314 { 316 - if (tcg_eventlog) { 317 - kfree(tcg_eventlog); 318 - tcg_eventlog = NULL; 315 + struct seq_file *seq = file->private_data; 316 + struct tpm_bios_log *log = seq->private; 317 + 318 + if (log) { 319 + kfree(log->bios_event_log); 320 + kfree(log); 319 321 } 322 + 320 323 return seq_release(inode, file); 321 324 } 322 325 ··· 372 367 }; 373 368 374 369 /* read binary bios log */ 375 - static int read_log(void) 370 + static int read_log(struct tpm_bios_log *log) 376 371 { 377 372 struct acpi_tcpa *buff; 378 373 acpi_status status; 379 374 void *virt; 380 375 381 - if (tcg_eventlog != NULL) { 376 + if (log->bios_event_log != NULL) { 382 377 printk(KERN_ERR 383 378 "%s: ERROR - Eventlog already initialized\n", 384 379 __func__); ··· 398 393 } 399 394 400 395 if (buff->log_max_len == 0) { 401 - printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", 402 - __func__); 396 + printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__); 403 397 return -EIO; 404 398 } 405 399 406 400 /* malloc EventLog space */ 407 - tcg_eventlog = kmalloc(buff->log_max_len, GFP_KERNEL); 408 - if (!tcg_eventlog) { 401 + log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL); 402 + if (!log->bios_event_log) { 409 403 printk 410 404 ("%s: ERROR - Not enough Memory for BIOS measurements\n", 411 405 __func__); 412 406 return -ENOMEM; 413 407 } 414 408 415 - tcg_eventlog_addr_limit = tcg_eventlog + buff->log_max_len; 409 + log->bios_event_log_end = log->bios_event_log + buff->log_max_len; 416 410 417 411 acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, &virt); 418 412 419 - memcpy(tcg_eventlog, virt, buff->log_max_len); 413 + memcpy(log->bios_event_log, virt, buff->log_max_len); 420 414 421 415 acpi_os_unmap_memory(virt, buff->log_max_len); 422 416 return 0; ··· 425 421 struct file *file) 426 422 { 427 423 int err; 424 + struct tpm_bios_log *log; 425 + struct seq_file *seq; 428 426 429 - if ((err = read_log())) 427 + log = kzalloc(sizeof(struct tpm_bios_log), GFP_KERNEL); 428 + if (!log) 429 + return -ENOMEM; 430 + 431 + if ((err = read_log(log))) 430 432 return err; 431 433 432 434 /* now register seq file */ 433 - return seq_open(file, &tpm_ascii_b_measurments_seqops); 435 + err = seq_open(file, &tpm_ascii_b_measurments_seqops); 436 + if (!err) { 437 + seq = file->private_data; 438 + seq->private = log; 439 + } else { 440 + kfree(log->bios_event_log); 441 + kfree(log); 442 + } 443 + return err; 434 444 } 435 445 436 446 struct file_operations tpm_ascii_bios_measurements_ops = { ··· 458 440 struct file *file) 459 441 { 460 442 int err; 443 + struct tpm_bios_log *log; 444 + struct seq_file *seq; 461 445 462 - if ((err = read_log())) 446 + log = kzalloc(sizeof(struct tpm_bios_log), GFP_KERNEL); 447 + if (!log) 448 + return -ENOMEM; 449 + 450 + if ((err = read_log(log))) 463 451 return err; 464 452 465 453 /* now register seq file */ 466 - return seq_open(file, &tpm_binary_b_measurments_seqops); 454 + err = seq_open(file, &tpm_binary_b_measurments_seqops); 455 + if (!err) { 456 + seq = file->private_data; 457 + seq->private = log; 458 + } else { 459 + kfree(log->bios_event_log); 460 + kfree(log); 461 + } 462 + return err; 467 463 } 468 464 469 465 struct file_operations tpm_binary_bios_measurements_ops = {