[PATCH] tpm: fix memory leak
[safe/jmp/linux-2.6] / drivers / char / tpm / tpm_bios.c
1 /*
2  * Copyright (C) 2005 IBM Corporation
3  *
4  * Authors:
5  *      Seiji Munetoh <munetoh@jp.ibm.com>
6  *      Stefan Berger <stefanb@us.ibm.com>
7  *      Reiner Sailer <sailer@watson.ibm.com>
8  *      Kylene Hall <kjhall@us.ibm.com>
9  *
10  * Access to the eventlog extended by the TCG BIOS of PC platform
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version
15  * 2 of the License, or (at your option) any later version.
16  *
17  */
18
19 #include <linux/seq_file.h>
20 #include <linux/fs.h>
21 #include <linux/security.h>
22 #include <linux/module.h>
23 #include <acpi/acpi.h>
24 #include <acpi/actypes.h>
25 #include <acpi/actbl.h>
26 #include "tpm.h"
27
28 #define TCG_EVENT_NAME_LEN_MAX  255
29 #define MAX_TEXT_EVENT          1000    /* Max event string length */
30 #define ACPI_TCPA_SIG           "TCPA"  /* 0x41504354 /'TCPA' */
31
32 struct tpm_bios_log {
33         void *bios_event_log;
34         void *bios_event_log_end;
35 };
36
37 struct acpi_tcpa {
38         struct acpi_table_header hdr;
39         u16 reserved;
40         u32 log_max_len __attribute__ ((packed));
41         u32 log_start_addr __attribute__ ((packed));
42 };
43
44 struct tcpa_event {
45         u32 pcr_index;
46         u32 event_type;
47         u8 pcr_value[20];       /* SHA1 */
48         u32 event_size;
49         u8 event_data[0];
50 };
51
52 enum tcpa_event_types {
53         PREBOOT = 0,
54         POST_CODE,
55         UNUSED,
56         NO_ACTION,
57         SEPARATOR,
58         ACTION,
59         EVENT_TAG,
60         SCRTM_CONTENTS,
61         SCRTM_VERSION,
62         CPU_MICROCODE,
63         PLATFORM_CONFIG_FLAGS,
64         TABLE_OF_DEVICES,
65         COMPACT_HASH,
66         IPL,
67         IPL_PARTITION_DATA,
68         NONHOST_CODE,
69         NONHOST_CONFIG,
70         NONHOST_INFO,
71 };
72
73 static const char* tcpa_event_type_strings[] = {
74         "PREBOOT",
75         "POST CODE",
76         "",
77         "NO ACTION",
78         "SEPARATOR",
79         "ACTION",
80         "EVENT TAG",
81         "S-CRTM Contents",
82         "S-CRTM Version",
83         "CPU Microcode",
84         "Platform Config Flags",
85         "Table of Devices",
86         "Compact Hash",
87         "IPL",
88         "IPL Partition Data",
89         "Non-Host Code",
90         "Non-Host Config",
91         "Non-Host Info"
92 };
93
94 enum tcpa_pc_event_ids {
95         SMBIOS = 1,
96         BIS_CERT,
97         POST_BIOS_ROM,
98         ESCD,
99         CMOS,
100         NVRAM,
101         OPTION_ROM_EXEC,
102         OPTION_ROM_CONFIG,
103         OPTION_ROM_MICROCODE,
104         S_CRTM_VERSION,
105         S_CRTM_CONTENTS,
106         POST_CONTENTS,
107 };
108
109 static const char* tcpa_pc_event_id_strings[] = {
110         ""
111         "SMBIOS",
112         "BIS Certificate",
113         "POST BIOS ",
114         "ESCD ",
115         "CMOS",
116         "NVRAM",
117         "Option ROM",
118         "Option ROM config",
119         "Option ROM microcode",
120         "S-CRTM Version",
121         "S-CRTM Contents",
122         "S-CRTM POST Contents",
123 };
124
125 /* returns pointer to start of pos. entry of tcg log */
126 static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos)
127 {
128         loff_t i;
129         struct tpm_bios_log *log = m->private;
130         void *addr = log->bios_event_log;
131         void *limit = log->bios_event_log_end;
132         struct tcpa_event *event;
133
134         /* read over *pos measurements */
135         for (i = 0; i < *pos; i++) {
136                 event = addr;
137
138                 if ((addr + sizeof(struct tcpa_event)) < limit) {
139                         if (event->event_type == 0 && event->event_size == 0)
140                                 return NULL;
141                         addr += sizeof(struct tcpa_event) + event->event_size;
142                 }
143         }
144
145         /* now check if current entry is valid */
146         if ((addr + sizeof(struct tcpa_event)) >= limit)
147                 return NULL;
148
149         event = addr;
150
151         if ((event->event_type == 0 && event->event_size == 0) ||
152             ((addr + sizeof(struct tcpa_event) + event->event_size) >= limit))
153                 return NULL;
154
155         return addr;
156 }
157
158 static void *tpm_bios_measurements_next(struct seq_file *m, void *v,
159                                         loff_t *pos)
160 {
161         struct tcpa_event *event = v;
162         struct tpm_bios_log *log = m->private;
163         void *limit = log->bios_event_log_end;
164
165         v += sizeof(struct tcpa_event) + event->event_size;
166
167         /* now check if current entry is valid */
168         if ((v + sizeof(struct tcpa_event)) >= limit)
169                 return NULL;
170
171         event = v;
172
173         if (event->event_type == 0 && event->event_size == 0)
174                 return NULL;
175
176         if ((event->event_type == 0 && event->event_size == 0) ||
177             ((v + sizeof(struct tcpa_event) + event->event_size) >= limit))
178                 return NULL;
179
180         (*pos)++;
181         return v;
182 }
183
184 static void tpm_bios_measurements_stop(struct seq_file *m, void *v)
185 {
186 }
187
188 static int get_event_name(char *dest, struct tcpa_event *event,
189                         unsigned char * event_entry)
190 {
191         const char *name = "";
192         char data[40] = "";
193         int i, n_len = 0, d_len = 0;
194         u32 event_id;
195
196         switch(event->event_type) {
197         case PREBOOT:
198         case POST_CODE:
199         case UNUSED:
200         case NO_ACTION:
201         case SCRTM_CONTENTS:
202         case SCRTM_VERSION:
203         case CPU_MICROCODE:
204         case PLATFORM_CONFIG_FLAGS:
205         case TABLE_OF_DEVICES:
206         case COMPACT_HASH:
207         case IPL:
208         case IPL_PARTITION_DATA:
209         case NONHOST_CODE:
210         case NONHOST_CONFIG:
211         case NONHOST_INFO:
212                 name = tcpa_event_type_strings[event->event_type];
213                 n_len = strlen(name);
214                 break;
215         case SEPARATOR:
216         case ACTION:
217                 if (MAX_TEXT_EVENT > event->event_size) {
218                         name = event_entry;
219                         n_len = event->event_size;
220                 }
221                 break;
222         case EVENT_TAG:
223                 event_id = be32_to_cpu(*((u32 *)event_entry));
224
225                 /* ToDo Row data -> Base64 */
226
227                 switch (event_id) {
228                 case SMBIOS:
229                 case BIS_CERT:
230                 case CMOS:
231                 case NVRAM:
232                 case OPTION_ROM_EXEC:
233                 case OPTION_ROM_CONFIG:
234                 case OPTION_ROM_MICROCODE:
235                 case S_CRTM_VERSION:
236                 case S_CRTM_CONTENTS:
237                 case POST_CONTENTS:
238                         name = tcpa_pc_event_id_strings[event_id];
239                         n_len = strlen(name);
240                         break;
241                 case POST_BIOS_ROM:
242                 case ESCD:
243                         name = tcpa_pc_event_id_strings[event_id];
244                         n_len = strlen(name);
245                         for (i = 0; i < 20; i++)
246                                 d_len += sprintf(data, "%02x",
247                                                 event_entry[8 + i]);
248                         break;
249                 default:
250                         break;
251                 }
252         default:
253                 break;
254         }
255
256         return snprintf(dest, MAX_TEXT_EVENT, "[%.*s%.*s]",
257                         n_len, name, d_len, data);
258
259 }
260
261 static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
262 {
263
264         char *eventname;
265         char data[4];
266         u32 help;
267         int i, len;
268         struct tcpa_event *event = (struct tcpa_event *) v;
269         unsigned char *event_entry =
270             (unsigned char *) (v + sizeof(struct tcpa_event));
271
272         eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
273         if (!eventname) {
274                 printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
275                        __func__);
276                 return -ENOMEM;
277         }
278
279         /* 1st: PCR used is in little-endian format (4 bytes) */
280         help = le32_to_cpu(event->pcr_index);
281         memcpy(data, &help, 4);
282         for (i = 0; i < 4; i++)
283                 seq_putc(m, data[i]);
284
285         /* 2nd: SHA1 (20 bytes) */
286         for (i = 0; i < 20; i++)
287                 seq_putc(m, event->pcr_value[i]);
288
289         /* 3rd: event type identifier (4 bytes) */
290         help = le32_to_cpu(event->event_type);
291         memcpy(data, &help, 4);
292         for (i = 0; i < 4; i++)
293                 seq_putc(m, data[i]);
294
295         len = 0;
296
297         len += get_event_name(eventname, event, event_entry);
298
299         /* 4th:  filename <= 255 + \'0' delimiter */
300         if (len > TCG_EVENT_NAME_LEN_MAX)
301                 len = TCG_EVENT_NAME_LEN_MAX;
302
303         for (i = 0; i < len; i++)
304                 seq_putc(m, eventname[i]);
305
306         /* 5th: delimiter */
307         seq_putc(m, '\0');
308
309         kfree(eventname);
310         return 0;
311 }
312
313 static int tpm_bios_measurements_release(struct inode *inode,
314                                          struct file *file)
315 {
316         struct seq_file *seq = file->private_data;
317         struct tpm_bios_log *log = seq->private;
318
319         if (log) {
320                 kfree(log->bios_event_log);
321                 kfree(log);
322         }
323
324         return seq_release(inode, file);
325 }
326
327 static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v)
328 {
329         int len = 0;
330         int i;
331         char *eventname;
332         struct tcpa_event *event = v;
333         unsigned char *event_entry =
334             (unsigned char *) (v + sizeof(struct tcpa_event));
335
336         eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
337         if (!eventname) {
338                 printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
339                        __func__);
340                 return -EFAULT;
341         }
342
343         seq_printf(m, "%2d ", event->pcr_index);
344
345         /* 2nd: SHA1 */
346         for (i = 0; i < 20; i++)
347                 seq_printf(m, "%02x", event->pcr_value[i]);
348
349         /* 3rd: event type identifier */
350         seq_printf(m, " %02x", event->event_type);
351
352         len += get_event_name(eventname, event, event_entry);
353
354         /* 4th: eventname <= max + \'0' delimiter */
355         seq_printf(m, " %s\n", eventname);
356
357         kfree(eventname);
358         return 0;
359 }
360
361 static struct seq_operations tpm_ascii_b_measurments_seqops = {
362         .start = tpm_bios_measurements_start,
363         .next = tpm_bios_measurements_next,
364         .stop = tpm_bios_measurements_stop,
365         .show = tpm_ascii_bios_measurements_show,
366 };
367
368 static struct seq_operations tpm_binary_b_measurments_seqops = {
369         .start = tpm_bios_measurements_start,
370         .next = tpm_bios_measurements_next,
371         .stop = tpm_bios_measurements_stop,
372         .show = tpm_binary_bios_measurements_show,
373 };
374
375 /* read binary bios log */
376 static int read_log(struct tpm_bios_log *log)
377 {
378         struct acpi_tcpa *buff;
379         acpi_status status;
380         struct acpi_table_header *virt;
381
382         if (log->bios_event_log != NULL) {
383                 printk(KERN_ERR
384                        "%s: ERROR - Eventlog already initialized\n",
385                        __func__);
386                 return -EFAULT;
387         }
388
389         /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
390         status = acpi_get_firmware_table(ACPI_TCPA_SIG, 1,
391                                          ACPI_LOGICAL_ADDRESSING,
392                                          (struct acpi_table_header **)
393                                          &buff);
394
395         if (ACPI_FAILURE(status)) {
396                 printk(KERN_ERR "%s: ERROR - Could not get TCPA table\n",
397                        __func__);
398                 return -EIO;
399         }
400
401         if (buff->log_max_len == 0) {
402                 printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
403                 return -EIO;
404         }
405
406         /* malloc EventLog space */
407         log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL);
408         if (!log->bios_event_log) {
409                 printk
410                     ("%s: ERROR - Not enough  Memory for BIOS measurements\n",
411                      __func__);
412                 return -ENOMEM;
413         }
414
415         log->bios_event_log_end = log->bios_event_log + buff->log_max_len;
416
417         acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) &virt);
418
419         memcpy(log->bios_event_log, virt, buff->log_max_len);
420
421         acpi_os_unmap_memory(virt, buff->log_max_len);
422         return 0;
423 }
424
425 static int tpm_ascii_bios_measurements_open(struct inode *inode,
426                                             struct file *file)
427 {
428         int err;
429         struct tpm_bios_log *log;
430         struct seq_file *seq;
431
432         log = kzalloc(sizeof(struct tpm_bios_log), GFP_KERNEL);
433         if (!log)
434                 return -ENOMEM;
435
436         if ((err = read_log(log)))
437                 return err;
438
439         /* now register seq file */
440         err = seq_open(file, &tpm_ascii_b_measurments_seqops);
441         if (!err) {
442                 seq = file->private_data;
443                 seq->private = log;
444         } else {
445                 kfree(log->bios_event_log);
446                 kfree(log);
447         }
448         return err;
449 }
450
451 struct file_operations tpm_ascii_bios_measurements_ops = {
452         .open = tpm_ascii_bios_measurements_open,
453         .read = seq_read,
454         .llseek = seq_lseek,
455         .release = tpm_bios_measurements_release,
456 };
457
458 static int tpm_binary_bios_measurements_open(struct inode *inode,
459                                              struct file *file)
460 {
461         int err;
462         struct tpm_bios_log *log;
463         struct seq_file *seq;
464
465         log = kzalloc(sizeof(struct tpm_bios_log), GFP_KERNEL);
466         if (!log)
467                 return -ENOMEM;
468
469         if ((err = read_log(log)))
470                 return err;
471
472         /* now register seq file */
473         err = seq_open(file, &tpm_binary_b_measurments_seqops);
474         if (!err) {
475                 seq = file->private_data;
476                 seq->private = log;
477         } else {
478                 kfree(log->bios_event_log);
479                 kfree(log);
480         }
481         return err;
482 }
483
484 struct file_operations tpm_binary_bios_measurements_ops = {
485         .open = tpm_binary_bios_measurements_open,
486         .read = seq_read,
487         .llseek = seq_lseek,
488         .release = tpm_bios_measurements_release,
489 };
490
491 static int is_bad(void *p)
492 {
493         if (!p)
494                 return 1;
495         if (IS_ERR(p) && (PTR_ERR(p) != -ENODEV))
496                 return 1;
497         return 0;
498 }
499
500 struct dentry **tpm_bios_log_setup(char *name)
501 {
502         struct dentry **ret = NULL, *tpm_dir, *bin_file, *ascii_file;
503
504         tpm_dir = securityfs_create_dir(name, NULL);
505         if (is_bad(tpm_dir))
506                 goto out;
507
508         bin_file =
509             securityfs_create_file("binary_bios_measurements",
510                                    S_IRUSR | S_IRGRP, tpm_dir, NULL,
511                                    &tpm_binary_bios_measurements_ops);
512         if (is_bad(bin_file))
513                 goto out_tpm;
514
515         ascii_file =
516             securityfs_create_file("ascii_bios_measurements",
517                                    S_IRUSR | S_IRGRP, tpm_dir, NULL,
518                                    &tpm_ascii_bios_measurements_ops);
519         if (is_bad(ascii_file))
520                 goto out_bin;
521
522         ret = kmalloc(3 * sizeof(struct dentry *), GFP_KERNEL);
523         if (!ret)
524                 goto out_ascii;
525
526         ret[0] = ascii_file;
527         ret[1] = bin_file;
528         ret[2] = tpm_dir;
529
530         return ret;
531
532 out_ascii:
533         securityfs_remove(ascii_file);
534 out_bin:
535         securityfs_remove(bin_file);
536 out_tpm:
537         securityfs_remove(tpm_dir);
538 out:
539         return NULL;
540 }
541 EXPORT_SYMBOL_GPL(tpm_bios_log_setup);
542
543 void tpm_bios_log_teardown(struct dentry **lst)
544 {
545         int i;
546
547         for (i = 0; i < 3; i++)
548                 securityfs_remove(lst[i]);
549 }
550 EXPORT_SYMBOL_GPL(tpm_bios_log_teardown);
551 MODULE_LICENSE("GPL");