Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754091AbbHDWAk (ORCPT ); Tue, 4 Aug 2015 18:00:40 -0400 Received: from mail-pd0-f175.google.com ([209.85.192.175]:36688 "EHLO mail-pd0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753422AbbHDWA3 (ORCPT ); Tue, 4 Aug 2015 18:00:29 -0400 From: "Luis R. Rodriguez" To: gregkh@linuxfoundation.org, ming.lei@canonical.com Cc: corbet@lwn.net, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, dwmw2@infradead.org, dhowells@redhat.com, seth.forshee@canonical.com, rusty@rustcorp.com.au, mmarek@suse.cz, mjg59@srcf.ucam.org, kyle@kernel.org, linux-security-module@vger.kernel.org, keyrings@linux-nfs.org, "Luis R. Rodriguez" Subject: [PATCH 4/4] firmware: generalize reading file contents as a helper Date: Tue, 4 Aug 2015 15:00:04 -0700 Message-Id: <1438725604-22795-5-git-send-email-mcgrof@do-not-panic.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1438725604-22795-1-git-send-email-mcgrof@do-not-panic.com> References: <1438725604-22795-1-git-send-email-mcgrof@do-not-panic.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3632 Lines: 146 From: David Howells We'll want to reuse this same code later in order to read two separate types of file contents. This generalizes fw_read_file() for reading a file rebrands it as fw_read_file(). This caller lets us pegs arbitrary data onto the target buffer and size if the file is found. While at it this cleans up the exit paths on fw_read_file(). Signed-off-by: David Howells Signed-off-by: Luis R. Rodriguez --- drivers/base/firmware_class.c | 62 +++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 736fb952b75b..dcc7036b4ad2 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -291,34 +291,51 @@ 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) +/* + * Read the contents of a file. + */ +static int fw_read_file(const char *path, void **_buf, size_t *_size) { - int size; + struct file *file; + size_t size; char *buf; int rc; + file = filp_open(path, O_RDONLY, 0); + if (IS_ERR(file)) + return PTR_ERR(file); + + rc = -EINVAL; if (!S_ISREG(file_inode(file)->i_mode)) - return -EINVAL; + goto err_file; size = i_size_read(file_inode(file)); if (size <= 0) - return -EINVAL; + goto err_file; + rc = -ENOMEM; buf = vmalloc(size); if (!buf) - return -ENOMEM; + goto err_file; + rc = kernel_read(file, 0, buf, size); + if (rc < 0) + goto err_buf; if (rc != size) { - if (rc > 0) - rc = -EIO; - goto fail; + rc = -EIO; + goto err_buf; } + rc = security_kernel_fw_from_file(file, buf, size); if (rc) - goto fail; - fw_buf->data = buf; - fw_buf->size = size; + goto err_buf; + + *_buf = buf; + *_size = size; return 0; -fail: + +err_buf: vfree(buf); +err_file: + fput(file); return rc; } @@ -332,19 +349,21 @@ static void fw_finish_direct_load(struct device *device, } static int fw_get_filesystem_firmware(struct device *device, - struct firmware_buf *buf) + struct firmware_buf *buf) { int i, len; int rc = -ENOENT; - char *path; + char *path = NULL; path = __getname(); if (!path) return -ENOMEM; + /* + * Try each possible firmware blob in turn till one doesn't produce + * ENOENT. + */ for (i = 0; i < ARRAY_SIZE(fw_path); i++) { - struct file *file; - /* skip the unset customized path */ if (!fw_path[i][0]) continue; @@ -356,23 +375,20 @@ static int fw_get_filesystem_firmware(struct device *device, break; } - file = filp_open(path, O_RDONLY, 0); - if (IS_ERR(file)) - continue; - rc = fw_read_file_contents(file, buf); - fput(file); + rc = fw_read_file(path, &buf->data, &buf->size); if (rc == 0) { dev_dbg(device, "system data: direct-loading firmware %s\n", buf->fw_id); fw_finish_direct_load(device, buf); goto out; - } else + } else if (rc != -ENOENT) { dev_warn(device, "system data, attempted to load %s, but failed with error %d\n", path, rc); + goto out; + } } out: __putname(path); - return rc; } -- 2.3.2.209.gd67f9d5.dirty -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/