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/base/firmware_class.c | |
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/base/firmware_class.c')
-rw-r--r-- | drivers/base/firmware_class.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index da77791793f1..bf424305f3dc 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/suspend.h> | 28 | #include <linux/suspend.h> |
29 | #include <linux/syscore_ops.h> | 29 | #include <linux/syscore_ops.h> |
30 | #include <linux/reboot.h> | 30 | #include <linux/reboot.h> |
31 | #include <linux/security.h> | ||
31 | 32 | ||
32 | #include <generated/utsrelease.h> | 33 | #include <generated/utsrelease.h> |
33 | 34 | ||
@@ -303,12 +304,17 @@ static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf) | |||
303 | if (rc != size) { | 304 | if (rc != size) { |
304 | if (rc > 0) | 305 | if (rc > 0) |
305 | rc = -EIO; | 306 | rc = -EIO; |
306 | vfree(buf); | 307 | goto fail; |
307 | return rc; | ||
308 | } | 308 | } |
309 | rc = security_kernel_fw_from_file(file, buf, size); | ||
310 | if (rc) | ||
311 | goto fail; | ||
309 | fw_buf->data = buf; | 312 | fw_buf->data = buf; |
310 | fw_buf->size = size; | 313 | fw_buf->size = size; |
311 | return 0; | 314 | return 0; |
315 | fail: | ||
316 | vfree(buf); | ||
317 | return rc; | ||
312 | } | 318 | } |
313 | 319 | ||
314 | static int fw_get_filesystem_firmware(struct device *device, | 320 | static int fw_get_filesystem_firmware(struct device *device, |
@@ -612,6 +618,7 @@ static ssize_t firmware_loading_store(struct device *dev, | |||
612 | { | 618 | { |
613 | struct firmware_priv *fw_priv = to_firmware_priv(dev); | 619 | struct firmware_priv *fw_priv = to_firmware_priv(dev); |
614 | struct firmware_buf *fw_buf; | 620 | struct firmware_buf *fw_buf; |
621 | ssize_t written = count; | ||
615 | int loading = simple_strtol(buf, NULL, 10); | 622 | int loading = simple_strtol(buf, NULL, 10); |
616 | int i; | 623 | int i; |
617 | 624 | ||
@@ -635,6 +642,8 @@ static ssize_t firmware_loading_store(struct device *dev, | |||
635 | break; | 642 | break; |
636 | case 0: | 643 | case 0: |
637 | if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) { | 644 | if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) { |
645 | int rc; | ||
646 | |||
638 | set_bit(FW_STATUS_DONE, &fw_buf->status); | 647 | set_bit(FW_STATUS_DONE, &fw_buf->status); |
639 | clear_bit(FW_STATUS_LOADING, &fw_buf->status); | 648 | clear_bit(FW_STATUS_LOADING, &fw_buf->status); |
640 | 649 | ||
@@ -644,10 +653,23 @@ static ssize_t firmware_loading_store(struct device *dev, | |||
644 | * see the mapped 'buf->data' once the loading | 653 | * see the mapped 'buf->data' once the loading |
645 | * is completed. | 654 | * is completed. |
646 | * */ | 655 | * */ |
647 | if (fw_map_pages_buf(fw_buf)) | 656 | rc = fw_map_pages_buf(fw_buf); |
657 | if (rc) | ||
648 | dev_err(dev, "%s: map pages failed\n", | 658 | dev_err(dev, "%s: map pages failed\n", |
649 | __func__); | 659 | __func__); |
660 | else | ||
661 | rc = security_kernel_fw_from_file(NULL, | ||
662 | fw_buf->data, fw_buf->size); | ||
663 | |||
664 | /* | ||
665 | * Same logic as fw_load_abort, only the DONE bit | ||
666 | * is ignored and we set ABORT only on failure. | ||
667 | */ | ||
650 | list_del_init(&fw_buf->pending_list); | 668 | list_del_init(&fw_buf->pending_list); |
669 | if (rc) { | ||
670 | set_bit(FW_STATUS_ABORT, &fw_buf->status); | ||
671 | written = rc; | ||
672 | } | ||
651 | complete_all(&fw_buf->completion); | 673 | complete_all(&fw_buf->completion); |
652 | break; | 674 | break; |
653 | } | 675 | } |
@@ -661,7 +683,7 @@ static ssize_t firmware_loading_store(struct device *dev, | |||
661 | } | 683 | } |
662 | out: | 684 | out: |
663 | mutex_unlock(&fw_lock); | 685 | mutex_unlock(&fw_lock); |
664 | return count; | 686 | return written; |
665 | } | 687 | } |
666 | 688 | ||
667 | static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); | 689 | static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); |