diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-06 11:06:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-06 11:06:39 -0400 |
commit | bb2cbf5e9367d8598fecd0c48dead69560750223 (patch) | |
tree | fb2c620451b90f41a31726bdd82077813f941e39 /drivers/char | |
parent | e7fda6c4c3c1a7d6996dd75fd84670fa0b5d448f (diff) | |
parent | 478d085524c57cf4283699f529d5a4c22188ea69 (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris:
"In this release:
- PKCS#7 parser for the key management subsystem from David Howells
- appoint Kees Cook as seccomp maintainer
- bugfixes and general maintenance across the subsystem"
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (94 commits)
X.509: Need to export x509_request_asymmetric_key()
netlabel: shorter names for the NetLabel catmap funcs/structs
netlabel: fix the catmap walking functions
netlabel: fix the horribly broken catmap functions
netlabel: fix a problem when setting bits below the previously lowest bit
PKCS#7: X.509 certificate issuer and subject are mandatory fields in the ASN.1
tpm: simplify code by using %*phN specifier
tpm: Provide a generic means to override the chip returned timeouts
tpm: missing tpm_chip_put in tpm_get_random()
tpm: Properly clean sysfs entries in error path
tpm: Add missing tpm_do_selftest to ST33 I2C driver
PKCS#7: Use x509_request_asymmetric_key()
Revert "selinux: fix the default socket labeling in sock_graft()"
X.509: x509_request_asymmetric_keys() doesn't need string length arguments
PKCS#7: fix sparse non static symbol warning
KEYS: revert encrypted key change
ima: add support for measuring and appraising firmware
firmware_class: perform new LSM checks
security: introduce kernel_fw_from_file hook
PKCS#7: Missing inclusion of linux/err.h
...
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/tpm/tpm-interface.c | 73 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_eventlog.c | 4 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_i2c_stm_st33.c | 1 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_tis.c | 31 |
4 files changed, 81 insertions, 28 deletions
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 62e10fd1e1cb..6af17002a115 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c | |||
@@ -491,11 +491,10 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type) | |||
491 | int tpm_get_timeouts(struct tpm_chip *chip) | 491 | int tpm_get_timeouts(struct tpm_chip *chip) |
492 | { | 492 | { |
493 | struct tpm_cmd_t tpm_cmd; | 493 | struct tpm_cmd_t tpm_cmd; |
494 | struct timeout_t *timeout_cap; | 494 | unsigned long new_timeout[4]; |
495 | unsigned long old_timeout[4]; | ||
495 | struct duration_t *duration_cap; | 496 | struct duration_t *duration_cap; |
496 | ssize_t rc; | 497 | ssize_t rc; |
497 | u32 timeout; | ||
498 | unsigned int scale = 1; | ||
499 | 498 | ||
500 | tpm_cmd.header.in = tpm_getcap_header; | 499 | tpm_cmd.header.in = tpm_getcap_header; |
501 | tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP; | 500 | tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP; |
@@ -529,25 +528,46 @@ int tpm_get_timeouts(struct tpm_chip *chip) | |||
529 | != sizeof(tpm_cmd.header.out) + sizeof(u32) + 4 * sizeof(u32)) | 528 | != sizeof(tpm_cmd.header.out) + sizeof(u32) + 4 * sizeof(u32)) |
530 | return -EINVAL; | 529 | return -EINVAL; |
531 | 530 | ||
532 | timeout_cap = &tpm_cmd.params.getcap_out.cap.timeout; | 531 | old_timeout[0] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.a); |
533 | /* Don't overwrite default if value is 0 */ | 532 | old_timeout[1] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.b); |
534 | timeout = be32_to_cpu(timeout_cap->a); | 533 | old_timeout[2] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.c); |
535 | if (timeout && timeout < 1000) { | 534 | old_timeout[3] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.d); |
536 | /* timeouts in msec rather usec */ | 535 | memcpy(new_timeout, old_timeout, sizeof(new_timeout)); |
537 | scale = 1000; | 536 | |
538 | chip->vendor.timeout_adjusted = true; | 537 | /* |
538 | * Provide ability for vendor overrides of timeout values in case | ||
539 | * of misreporting. | ||
540 | */ | ||
541 | if (chip->ops->update_timeouts != NULL) | ||
542 | chip->vendor.timeout_adjusted = | ||
543 | chip->ops->update_timeouts(chip, new_timeout); | ||
544 | |||
545 | if (!chip->vendor.timeout_adjusted) { | ||
546 | /* Don't overwrite default if value is 0 */ | ||
547 | if (new_timeout[0] != 0 && new_timeout[0] < 1000) { | ||
548 | int i; | ||
549 | |||
550 | /* timeouts in msec rather usec */ | ||
551 | for (i = 0; i != ARRAY_SIZE(new_timeout); i++) | ||
552 | new_timeout[i] *= 1000; | ||
553 | chip->vendor.timeout_adjusted = true; | ||
554 | } | ||
555 | } | ||
556 | |||
557 | /* Report adjusted timeouts */ | ||
558 | if (chip->vendor.timeout_adjusted) { | ||
559 | dev_info(chip->dev, | ||
560 | HW_ERR "Adjusting reported timeouts: A %lu->%luus B %lu->%luus C %lu->%luus D %lu->%luus\n", | ||
561 | old_timeout[0], new_timeout[0], | ||
562 | old_timeout[1], new_timeout[1], | ||
563 | old_timeout[2], new_timeout[2], | ||
564 | old_timeout[3], new_timeout[3]); | ||
539 | } | 565 | } |
540 | if (timeout) | 566 | |
541 | chip->vendor.timeout_a = usecs_to_jiffies(timeout * scale); | 567 | chip->vendor.timeout_a = usecs_to_jiffies(new_timeout[0]); |
542 | timeout = be32_to_cpu(timeout_cap->b); | 568 | chip->vendor.timeout_b = usecs_to_jiffies(new_timeout[1]); |
543 | if (timeout) | 569 | chip->vendor.timeout_c = usecs_to_jiffies(new_timeout[2]); |
544 | chip->vendor.timeout_b = usecs_to_jiffies(timeout * scale); | 570 | chip->vendor.timeout_d = usecs_to_jiffies(new_timeout[3]); |
545 | timeout = be32_to_cpu(timeout_cap->c); | ||
546 | if (timeout) | ||
547 | chip->vendor.timeout_c = usecs_to_jiffies(timeout * scale); | ||
548 | timeout = be32_to_cpu(timeout_cap->d); | ||
549 | if (timeout) | ||
550 | chip->vendor.timeout_d = usecs_to_jiffies(timeout * scale); | ||
551 | 571 | ||
552 | duration: | 572 | duration: |
553 | tpm_cmd.header.in = tpm_getcap_header; | 573 | tpm_cmd.header.in = tpm_getcap_header; |
@@ -991,13 +1011,13 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max) | |||
991 | int err, total = 0, retries = 5; | 1011 | int err, total = 0, retries = 5; |
992 | u8 *dest = out; | 1012 | u8 *dest = out; |
993 | 1013 | ||
1014 | if (!out || !num_bytes || max > TPM_MAX_RNG_DATA) | ||
1015 | return -EINVAL; | ||
1016 | |||
994 | chip = tpm_chip_find_get(chip_num); | 1017 | chip = tpm_chip_find_get(chip_num); |
995 | if (chip == NULL) | 1018 | if (chip == NULL) |
996 | return -ENODEV; | 1019 | return -ENODEV; |
997 | 1020 | ||
998 | if (!out || !num_bytes || max > TPM_MAX_RNG_DATA) | ||
999 | return -EINVAL; | ||
1000 | |||
1001 | do { | 1021 | do { |
1002 | tpm_cmd.header.in = tpm_getrandom_header; | 1022 | tpm_cmd.header.in = tpm_getrandom_header; |
1003 | tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes); | 1023 | tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes); |
@@ -1016,6 +1036,7 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max) | |||
1016 | num_bytes -= recd; | 1036 | num_bytes -= recd; |
1017 | } while (retries-- && total < max); | 1037 | } while (retries-- && total < max); |
1018 | 1038 | ||
1039 | tpm_chip_put(chip); | ||
1019 | return total ? total : -EIO; | 1040 | return total ? total : -EIO; |
1020 | } | 1041 | } |
1021 | EXPORT_SYMBOL_GPL(tpm_get_random); | 1042 | EXPORT_SYMBOL_GPL(tpm_get_random); |
@@ -1095,7 +1116,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, | |||
1095 | goto del_misc; | 1116 | goto del_misc; |
1096 | 1117 | ||
1097 | if (tpm_add_ppi(&dev->kobj)) | 1118 | if (tpm_add_ppi(&dev->kobj)) |
1098 | goto del_misc; | 1119 | goto del_sysfs; |
1099 | 1120 | ||
1100 | chip->bios_dir = tpm_bios_log_setup(chip->devname); | 1121 | chip->bios_dir = tpm_bios_log_setup(chip->devname); |
1101 | 1122 | ||
@@ -1106,6 +1127,8 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, | |||
1106 | 1127 | ||
1107 | return chip; | 1128 | return chip; |
1108 | 1129 | ||
1130 | del_sysfs: | ||
1131 | tpm_sysfs_del_device(chip); | ||
1109 | del_misc: | 1132 | del_misc: |
1110 | tpm_dev_del_device(chip); | 1133 | tpm_dev_del_device(chip); |
1111 | put_device: | 1134 | put_device: |
diff --git a/drivers/char/tpm/tpm_eventlog.c b/drivers/char/tpm/tpm_eventlog.c index 59f7cb28260b..3a56a131586c 100644 --- a/drivers/char/tpm/tpm_eventlog.c +++ b/drivers/char/tpm/tpm_eventlog.c | |||
@@ -235,7 +235,6 @@ static int tpm_bios_measurements_release(struct inode *inode, | |||
235 | static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v) | 235 | static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v) |
236 | { | 236 | { |
237 | int len = 0; | 237 | int len = 0; |
238 | int i; | ||
239 | char *eventname; | 238 | char *eventname; |
240 | struct tcpa_event *event = v; | 239 | struct tcpa_event *event = v; |
241 | unsigned char *event_entry = | 240 | unsigned char *event_entry = |
@@ -251,8 +250,7 @@ static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v) | |||
251 | seq_printf(m, "%2d ", event->pcr_index); | 250 | seq_printf(m, "%2d ", event->pcr_index); |
252 | 251 | ||
253 | /* 2nd: SHA1 */ | 252 | /* 2nd: SHA1 */ |
254 | for (i = 0; i < 20; i++) | 253 | seq_printf(m, "%20phN", event->pcr_value); |
255 | seq_printf(m, "%02x", event->pcr_value[i]); | ||
256 | 254 | ||
257 | /* 3rd: event type identifier */ | 255 | /* 3rd: event type identifier */ |
258 | seq_printf(m, " %02x", event->event_type); | 256 | seq_printf(m, " %02x", event->event_type); |
diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c index 3b7bf2162898..4669e3713428 100644 --- a/drivers/char/tpm/tpm_i2c_stm_st33.c +++ b/drivers/char/tpm/tpm_i2c_stm_st33.c | |||
@@ -714,6 +714,7 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
714 | } | 714 | } |
715 | 715 | ||
716 | tpm_get_timeouts(chip); | 716 | tpm_get_timeouts(chip); |
717 | tpm_do_selftest(chip); | ||
717 | 718 | ||
718 | dev_info(chip->dev, "TPM I2C Initialized\n"); | 719 | dev_info(chip->dev, "TPM I2C Initialized\n"); |
719 | return 0; | 720 | return 0; |
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index a9ed2270c25d..2c46734b266d 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -373,6 +373,36 @@ out_err: | |||
373 | return rc; | 373 | return rc; |
374 | } | 374 | } |
375 | 375 | ||
376 | struct tis_vendor_timeout_override { | ||
377 | u32 did_vid; | ||
378 | unsigned long timeout_us[4]; | ||
379 | }; | ||
380 | |||
381 | static const struct tis_vendor_timeout_override vendor_timeout_overrides[] = { | ||
382 | /* Atmel 3204 */ | ||
383 | { 0x32041114, { (TIS_SHORT_TIMEOUT*1000), (TIS_LONG_TIMEOUT*1000), | ||
384 | (TIS_SHORT_TIMEOUT*1000), (TIS_SHORT_TIMEOUT*1000) } }, | ||
385 | }; | ||
386 | |||
387 | static bool tpm_tis_update_timeouts(struct tpm_chip *chip, | ||
388 | unsigned long *timeout_cap) | ||
389 | { | ||
390 | int i; | ||
391 | u32 did_vid; | ||
392 | |||
393 | did_vid = ioread32(chip->vendor.iobase + TPM_DID_VID(0)); | ||
394 | |||
395 | for (i = 0; i != ARRAY_SIZE(vendor_timeout_overrides); i++) { | ||
396 | if (vendor_timeout_overrides[i].did_vid != did_vid) | ||
397 | continue; | ||
398 | memcpy(timeout_cap, vendor_timeout_overrides[i].timeout_us, | ||
399 | sizeof(vendor_timeout_overrides[i].timeout_us)); | ||
400 | return true; | ||
401 | } | ||
402 | |||
403 | return false; | ||
404 | } | ||
405 | |||
376 | /* | 406 | /* |
377 | * Early probing for iTPM with STS_DATA_EXPECT flaw. | 407 | * Early probing for iTPM with STS_DATA_EXPECT flaw. |
378 | * Try sending command without itpm flag set and if that | 408 | * Try sending command without itpm flag set and if that |
@@ -437,6 +467,7 @@ static const struct tpm_class_ops tpm_tis = { | |||
437 | .recv = tpm_tis_recv, | 467 | .recv = tpm_tis_recv, |
438 | .send = tpm_tis_send, | 468 | .send = tpm_tis_send, |
439 | .cancel = tpm_tis_ready, | 469 | .cancel = tpm_tis_ready, |
470 | .update_timeouts = tpm_tis_update_timeouts, | ||
440 | .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | 471 | .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, |
441 | .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | 472 | .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, |
442 | .req_canceled = tpm_tis_req_canceled, | 473 | .req_canceled = tpm_tis_req_canceled, |