Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965633AbbLWVgL (ORCPT ); Wed, 23 Dec 2015 16:36:11 -0500 Received: from mail-pf0-f182.google.com ([209.85.192.182]:36070 "EHLO mail-pf0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965544AbbLWVfb (ORCPT ); Wed, 23 Dec 2015 16:35:31 -0500 From: "Luis R. Rodriguez" To: gregkh@linuxfoundation.org, ming.lei@canonical.com Cc: jwboyer@fedoraproject.org, johannes@sipsolutions.net, luto@amacapital.net, corbet@lwn.net, dwmw2@infradead.org, dhowells@redhat.com, seth.forshee@canonical.com, rusty@rustcorp.com.au, mmarek@suse.cz, mjg59@srcf.ucam.org, kyle@kernel.org, zohar@linux.vnet.ibm.com, dmitry.kasatkin@gmail.com, vgoyal@redhat.com, computersforpeace@gmail.com, keescook@chromium.org, shuahkh@osg.samsung.com, torvalds@linux-foundation.org, linux-security-module@vger.kernel.org, keyrings@linux-nfs.org, linux-kernel@vger.kernel.org, "Luis R . Rodriguez" Subject: [PATCH v3 4/5] firmware: generalize reading file contents as a helper Date: Wed, 23 Dec 2015 13:34:56 -0800 Message-Id: <1450906497-24179-5-git-send-email-mcgrof@do-not-panic.com> X-Mailer: git-send-email 2.6.1 In-Reply-To: <1450906497-24179-1-git-send-email-mcgrof@do-not-panic.com> References: <1450906497-24179-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: 3958 Lines: 154 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_contents() for reading a file and rebrands it as fw_read_file(). This new caller is now generic: the path used can be arbitrary and the caller is also agnostic to the firmware_class code now, this begs the possibility of code re-use with other similar callers in the kernel. For instance in the future we may want to share a solution with: - firmware_class: fw_read_file() - module: kernel_read() - kexec: copy_file_fd() While at it this also cleans up the exit paths on fw_read_file(). Reviewed-by: Josh Boyer 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 e10a5349aa61..cd51a90ed012 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.6.2 -- 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/