diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-17 11:33:45 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-17 11:33:45 -0700 |
commit | bb7aeae3d680c2c777f54274b0270ced0599f33d (patch) | |
tree | 4801a103c2b157b5019cf38a19dc67d54bf38453 /drivers/base | |
parent | 70477371dc350746d10431d74f0f213a8d59924c (diff) | |
parent | 88a1b564a20e371e6be41b39b85673e9c1959491 (diff) | |
download | linux-bb7aeae3d680c2c777f54274b0270ced0599f33d.tar.bz2 |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security layer updates from James Morris:
"There are a bunch of fixes to the TPM, IMA, and Keys code, with minor
fixes scattered across the subsystem.
IMA now requires signed policy, and that policy is also now measured
and appraised"
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (67 commits)
X.509: Make algo identifiers text instead of enum
akcipher: Move the RSA DER encoding check to the crypto layer
crypto: Add hash param to pkcs1pad
sign-file: fix build with CMS support disabled
MAINTAINERS: update tpmdd urls
MODSIGN: linux/string.h should be #included to get memcpy()
certs: Fix misaligned data in extra certificate list
X.509: Handle midnight alternative notation in GeneralizedTime
X.509: Support leap seconds
Handle ISO 8601 leap seconds and encodings of midnight in mktime64()
X.509: Fix leap year handling again
PKCS#7: fix unitialized boolean 'want'
firmware: change kernel read fail to dev_dbg()
KEYS: Use the symbol value for list size, updated by scripts/insert-sys-cert
KEYS: Reserve an extra certificate symbol for inserting without recompiling
modsign: hide openssl output in silent builds
tpm_tis: fix build warning with tpm_tis_resume
ima: require signed IMA policy
ima: measure and appraise the IMA policy itself
ima: load policy using path
...
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/firmware_class.c | 78 |
1 files changed, 27 insertions, 51 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index b9250e564ebf..f3f7215ad378 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -23,6 +23,7 @@ #include <linux/sched.h> #include <linux/file.h> #include <linux/list.h> +#include <linux/fs.h> #include <linux/async.h> #include <linux/pm.h> #include <linux/suspend.h> @@ -291,40 +292,19 @@ static const char * const fw_path[] = { module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644); MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path"); -static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf) +static void fw_finish_direct_load(struct device *device, + struct firmware_buf *buf) { - int size; - char *buf; - int rc; - - if (!S_ISREG(file_inode(file)->i_mode)) - return -EINVAL; - size = i_size_read(file_inode(file)); - if (size <= 0) - return -EINVAL; - buf = vmalloc(size); - if (!buf) - return -ENOMEM; - rc = kernel_read(file, 0, buf, size); - if (rc != size) { - if (rc > 0) - rc = -EIO; - goto fail; - } - rc = security_kernel_fw_from_file(file, buf, size); - if (rc) - goto fail; - fw_buf->data = buf; - fw_buf->size = size; - return 0; -fail: - vfree(buf); - return rc; + mutex_lock(&fw_lock); + set_bit(FW_STATUS_DONE, &buf->status); + complete_all(&buf->completion); + mutex_unlock(&fw_lock); } static int fw_get_filesystem_firmware(struct device *device, struct firmware_buf *buf) { + loff_t size; int i, len; int rc = -ENOENT; char *path; @@ -334,8 +314,6 @@ static int fw_get_filesystem_firmware(struct device *device, return -ENOMEM; for (i = 0; i < ARRAY_SIZE(fw_path); i++) { - struct file *file; - /* skip the unset customized path */ if (!fw_path[i][0]) continue; @@ -347,28 +325,25 @@ static int fw_get_filesystem_firmware(struct device *device, break; } - file = filp_open(path, O_RDONLY, 0); - if (IS_ERR(file)) + buf->size = 0; + rc = kernel_read_file_from_path(path, &buf->data, &size, + INT_MAX, READING_FIRMWARE); + if (rc) { + if (rc == -ENOENT) + dev_dbg(device, "loading %s failed with error %d\n", + path, rc); + else + dev_warn(device, "loading %s failed with error %d\n", + path, rc); continue; - rc = fw_read_file_contents(file, buf); - fput(file); - if (rc) - dev_warn(device, "firmware, attempted to load %s, but failed with error %d\n", - path, rc); - else - break; + } + dev_dbg(device, "direct-loading %s\n", buf->fw_id); + buf->size = size; + fw_finish_direct_load(device, buf); + break; } __putname(path); - if (!rc) { - dev_dbg(device, "firmware: direct-loading firmware %s\n", - buf->fw_id); - mutex_lock(&fw_lock); - set_bit(FW_STATUS_DONE, &buf->status); - complete_all(&buf->completion); - mutex_unlock(&fw_lock); - } - return rc; } @@ -685,8 +660,9 @@ static ssize_t firmware_loading_store(struct device *dev, dev_err(dev, "%s: map pages failed\n", __func__); else - rc = security_kernel_fw_from_file(NULL, - fw_buf->data, fw_buf->size); + rc = security_kernel_post_read_file(NULL, + fw_buf->data, fw_buf->size, + READING_FIRMWARE); /* * Same logic as fw_load_abort, only the DONE bit @@ -1051,7 +1027,7 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name, } if (fw_get_builtin_firmware(firmware, name)) { - dev_dbg(device, "firmware: using built-in firmware %s\n", name); + dev_dbg(device, "using built-in %s\n", name); return 0; /* assigned */ } |