aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/firmware_class.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-03-17 14:33:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-17 14:33:45 -0400
commitbb7aeae3d680c2c777f54274b0270ced0599f33d (patch)
tree4801a103c2b157b5019cf38a19dc67d54bf38453 /drivers/base/firmware_class.c
parent70477371dc350746d10431d74f0f213a8d59924c (diff)
parent88a1b564a20e371e6be41b39b85673e9c1959491 (diff)
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/firmware_class.c')
-rw-r--r--drivers/base/firmware_class.c78
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 @@
23#include <linux/sched.h> 23#include <linux/sched.h>
24#include <linux/file.h> 24#include <linux/file.h>
25#include <linux/list.h> 25#include <linux/list.h>
26#include <linux/fs.h>
26#include <linux/async.h> 27#include <linux/async.h>
27#include <linux/pm.h> 28#include <linux/pm.h>
28#include <linux/suspend.h> 29#include <linux/suspend.h>
@@ -291,40 +292,19 @@ static const char * const fw_path[] = {
291module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644); 292module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644);
292MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path"); 293MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path");
293 294
294static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf) 295static void fw_finish_direct_load(struct device *device,
296 struct firmware_buf *buf)
295{ 297{
296 int size; 298 mutex_lock(&fw_lock);
297 char *buf; 299 set_bit(FW_STATUS_DONE, &buf->status);
298 int rc; 300 complete_all(&buf->completion);
299 301 mutex_unlock(&fw_lock);
300 if (!S_ISREG(file_inode(file)->i_mode))
301 return -EINVAL;
302 size = i_size_read(file_inode(file));
303 if (size <= 0)
304 return -EINVAL;
305 buf = vmalloc(size);
306 if (!buf)
307 return -ENOMEM;
308 rc = kernel_read(file, 0, buf, size);
309 if (rc != size) {
310 if (rc > 0)
311 rc = -EIO;
312 goto fail;
313 }
314 rc = security_kernel_fw_from_file(file, buf, size);
315 if (rc)
316 goto fail;
317 fw_buf->data = buf;
318 fw_buf->size = size;
319 return 0;
320fail:
321 vfree(buf);
322 return rc;
323} 302}
324 303
325static int fw_get_filesystem_firmware(struct device *device, 304static int fw_get_filesystem_firmware(struct device *device,
326 struct firmware_buf *buf) 305 struct firmware_buf *buf)
327{ 306{
307 loff_t size;
328 int i, len; 308 int i, len;
329 int rc = -ENOENT; 309 int rc = -ENOENT;
330 char *path; 310 char *path;
@@ -334,8 +314,6 @@ static int fw_get_filesystem_firmware(struct device *device,
334 return -ENOMEM; 314 return -ENOMEM;
335 315
336 for (i = 0; i < ARRAY_SIZE(fw_path); i++) { 316 for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
337 struct file *file;
338
339 /* skip the unset customized path */ 317 /* skip the unset customized path */
340 if (!fw_path[i][0]) 318 if (!fw_path[i][0])
341 continue; 319 continue;
@@ -347,28 +325,25 @@ static int fw_get_filesystem_firmware(struct device *device,
347 break; 325 break;
348 } 326 }
349 327
350 file = filp_open(path, O_RDONLY, 0); 328 buf->size = 0;
351 if (IS_ERR(file)) 329 rc = kernel_read_file_from_path(path, &buf->data, &size,
330 INT_MAX, READING_FIRMWARE);
331 if (rc) {
332 if (rc == -ENOENT)
333 dev_dbg(device, "loading %s failed with error %d\n",
334 path, rc);
335 else
336 dev_warn(device, "loading %s failed with error %d\n",
337 path, rc);
352 continue; 338 continue;
353 rc = fw_read_file_contents(file, buf); 339 }
354 fput(file); 340 dev_dbg(device, "direct-loading %s\n", buf->fw_id);
355 if (rc) 341 buf->size = size;
356 dev_warn(device, "firmware, attempted to load %s, but failed with error %d\n", 342 fw_finish_direct_load(device, buf);
357 path, rc); 343 break;
358 else
359 break;
360 } 344 }
361 __putname(path); 345 __putname(path);
362 346
363 if (!rc) {
364 dev_dbg(device, "firmware: direct-loading firmware %s\n",
365 buf->fw_id);
366 mutex_lock(&fw_lock);
367 set_bit(FW_STATUS_DONE, &buf->status);
368 complete_all(&buf->completion);
369 mutex_unlock(&fw_lock);
370 }
371
372 return rc; 347 return rc;
373} 348}
374 349
@@ -685,8 +660,9 @@ static ssize_t firmware_loading_store(struct device *dev,
685 dev_err(dev, "%s: map pages failed\n", 660 dev_err(dev, "%s: map pages failed\n",
686 __func__); 661 __func__);
687 else 662 else
688 rc = security_kernel_fw_from_file(NULL, 663 rc = security_kernel_post_read_file(NULL,
689 fw_buf->data, fw_buf->size); 664 fw_buf->data, fw_buf->size,
665 READING_FIRMWARE);
690 666
691 /* 667 /*
692 * Same logic as fw_load_abort, only the DONE bit 668 * Same logic as fw_load_abort, only the DONE bit
@@ -1051,7 +1027,7 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name,
1051 } 1027 }
1052 1028
1053 if (fw_get_builtin_firmware(firmware, name)) { 1029 if (fw_get_builtin_firmware(firmware, name)) {
1054 dev_dbg(device, "firmware: using built-in firmware %s\n", name); 1030 dev_dbg(device, "using built-in %s\n", name);
1055 return 0; /* assigned */ 1031 return 0; /* assigned */
1056 } 1032 }
1057 1033