aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/firmware_class.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index d276e33880be..63f165c59da8 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
@@ -308,12 +309,17 @@ static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
308 if (rc != size) { 309 if (rc != size) {
309 if (rc > 0) 310 if (rc > 0)
310 rc = -EIO; 311 rc = -EIO;
311 vfree(buf); 312 goto fail;
312 return rc;
313 } 313 }
314 rc = security_kernel_fw_from_file(file, buf, size);
315 if (rc)
316 goto fail;
314 fw_buf->data = buf; 317 fw_buf->data = buf;
315 fw_buf->size = size; 318 fw_buf->size = size;
316 return 0; 319 return 0;
320fail:
321 vfree(buf);
322 return rc;
317} 323}
318 324
319static int fw_get_filesystem_firmware(struct device *device, 325static int fw_get_filesystem_firmware(struct device *device,
@@ -617,6 +623,7 @@ static ssize_t firmware_loading_store(struct device *dev,
617{ 623{
618 struct firmware_priv *fw_priv = to_firmware_priv(dev); 624 struct firmware_priv *fw_priv = to_firmware_priv(dev);
619 struct firmware_buf *fw_buf; 625 struct firmware_buf *fw_buf;
626 ssize_t written = count;
620 int loading = simple_strtol(buf, NULL, 10); 627 int loading = simple_strtol(buf, NULL, 10);
621 int i; 628 int i;
622 629
@@ -640,6 +647,8 @@ static ssize_t firmware_loading_store(struct device *dev,
640 break; 647 break;
641 case 0: 648 case 0:
642 if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) { 649 if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) {
650 int rc;
651
643 set_bit(FW_STATUS_DONE, &fw_buf->status); 652 set_bit(FW_STATUS_DONE, &fw_buf->status);
644 clear_bit(FW_STATUS_LOADING, &fw_buf->status); 653 clear_bit(FW_STATUS_LOADING, &fw_buf->status);
645 654
@@ -649,10 +658,23 @@ static ssize_t firmware_loading_store(struct device *dev,
649 * see the mapped 'buf->data' once the loading 658 * see the mapped 'buf->data' once the loading
650 * is completed. 659 * is completed.
651 * */ 660 * */
652 if (fw_map_pages_buf(fw_buf)) 661 rc = fw_map_pages_buf(fw_buf);
662 if (rc)
653 dev_err(dev, "%s: map pages failed\n", 663 dev_err(dev, "%s: map pages failed\n",
654 __func__); 664 __func__);
665 else
666 rc = security_kernel_fw_from_file(NULL,
667 fw_buf->data, fw_buf->size);
668
669 /*
670 * Same logic as fw_load_abort, only the DONE bit
671 * is ignored and we set ABORT only on failure.
672 */
655 list_del_init(&fw_buf->pending_list); 673 list_del_init(&fw_buf->pending_list);
674 if (rc) {
675 set_bit(FW_STATUS_ABORT, &fw_buf->status);
676 written = rc;
677 }
656 complete_all(&fw_buf->completion); 678 complete_all(&fw_buf->completion);
657 break; 679 break;
658 } 680 }
@@ -666,7 +688,7 @@ static ssize_t firmware_loading_store(struct device *dev,
666 } 688 }
667out: 689out:
668 mutex_unlock(&fw_lock); 690 mutex_unlock(&fw_lock);
669 return count; 691 return written;
670} 692}
671 693
672static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); 694static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store);