From: Scott Branden <scott.branden@broadcom.com>
To: Luis Chamberlain <mcgrof@kernel.org>,
Wolfram Sang <wsa@kernel.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
David Brown <david.brown@linaro.org>,
Alexander Viro <viro@zeniv.linux.org.uk>,
Shuah Khan <shuah@kernel.org>,
bjorn.andersson@linaro.org,
Shuah Khan <skhan@linuxfoundation.org>,
Arnd Bergmann <arnd@arndb.de>
Cc: Mimi Zohar <zohar@linux.ibm.com>,
"Rafael J . Wysocki" <rafael@kernel.org>,
linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
linux-fsdevel@vger.kernel.org,
BCM Kernel Feedback <bcm-kernel-feedback-list@broadcom.com>,
Olof Johansson <olof@lixom.net>,
Andrew Morton <akpm@linux-foundation.org>,
Dan Carpenter <dan.carpenter@oracle.com>,
Colin Ian King <colin.king@canonical.com>,
Kees Cook <keescook@chromium.org>, Takashi Iwai <tiwai@suse.de>,
linux-kselftest@vger.kernel.org, Andy Gross <agross@kernel.org>,
linux-integrity@vger.kernel.org,
linux-security-module@vger.kernel.org,
Scott Branden <scott.branden@broadcom.com>
Subject: [PATCH v8 1/8] fs: introduce kernel_pread_file* support
Date: Tue, 9 Jun 2020 15:56:49 -0700 [thread overview]
Message-ID: <20200609225656.18663-2-scott.branden@broadcom.com> (raw)
In-Reply-To: <20200609225656.18663-1-scott.branden@broadcom.com>
Add kernel_pread_file* support to kernel to allow for partial read
of files with an offset into the file.
Signed-off-by: Scott Branden <scott.branden@broadcom.com>
---
fs/exec.c | 93 ++++++++++++++++++++++++++++++++++------------
include/linux/fs.h | 15 ++++++++
2 files changed, 85 insertions(+), 23 deletions(-)
diff --git a/fs/exec.c b/fs/exec.c
index 7b7cbb180785..c557b4b31d0f 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -927,10 +927,14 @@ struct file *open_exec(const char *name)
}
EXPORT_SYMBOL(open_exec);
-int kernel_read_file(struct file *file, void **buf, loff_t *size,
- loff_t max_size, enum kernel_read_file_id id)
-{
- loff_t i_size, pos;
+int kernel_pread_file(struct file *file, void **buf, loff_t *size,
+ loff_t max_size, loff_t pos,
+ enum kernel_read_file_id id)
+{
+ loff_t alloc_size;
+ loff_t buf_pos;
+ loff_t read_end;
+ loff_t i_size;
ssize_t bytes = 0;
int ret;
@@ -950,21 +954,32 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
ret = -EINVAL;
goto out;
}
- if (i_size > SIZE_MAX || (max_size > 0 && i_size > max_size)) {
+
+ /* Default read to end of file */
+ read_end = i_size;
+
+ /* Allow reading partial portion of file */
+ if ((id == READING_FIRMWARE_PARTIAL_READ) &&
+ (i_size > (pos + max_size)))
+ read_end = pos + max_size;
+
+ alloc_size = read_end - pos;
+ if (i_size > SIZE_MAX || (max_size > 0 && alloc_size > max_size)) {
ret = -EFBIG;
goto out;
}
- if (id != READING_FIRMWARE_PREALLOC_BUFFER)
- *buf = vmalloc(i_size);
+ if ((id != READING_FIRMWARE_PARTIAL_READ) &&
+ (id != READING_FIRMWARE_PREALLOC_BUFFER))
+ *buf = vmalloc(alloc_size);
if (!*buf) {
ret = -ENOMEM;
goto out;
}
- pos = 0;
- while (pos < i_size) {
- bytes = kernel_read(file, *buf + pos, i_size - pos, &pos);
+ buf_pos = 0;
+ while (pos < read_end) {
+ bytes = kernel_read(file, *buf + buf_pos, read_end - pos, &pos);
if (bytes < 0) {
ret = bytes;
goto out_free;
@@ -972,20 +987,23 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
if (bytes == 0)
break;
+
+ buf_pos += bytes;
}
- if (pos != i_size) {
+ if (pos != read_end) {
ret = -EIO;
goto out_free;
}
- ret = security_kernel_post_read_file(file, *buf, i_size, id);
+ ret = security_kernel_post_read_file(file, *buf, alloc_size, id);
if (!ret)
*size = pos;
out_free:
if (ret < 0) {
- if (id != READING_FIRMWARE_PREALLOC_BUFFER) {
+ if ((id != READING_FIRMWARE_PARTIAL_READ) &&
+ (id != READING_FIRMWARE_PREALLOC_BUFFER)) {
vfree(*buf);
*buf = NULL;
}
@@ -995,10 +1013,18 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
allow_write_access(file);
return ret;
}
+
+int kernel_read_file(struct file *file, void **buf, loff_t *size,
+ loff_t max_size, enum kernel_read_file_id id)
+{
+ return kernel_pread_file(file, buf, size, max_size, 0, id);
+}
EXPORT_SYMBOL_GPL(kernel_read_file);
-int kernel_read_file_from_path(const char *path, void **buf, loff_t *size,
- loff_t max_size, enum kernel_read_file_id id)
+int kernel_pread_file_from_path(const char *path, void **buf,
+ loff_t *size,
+ loff_t max_size, loff_t pos,
+ enum kernel_read_file_id id)
{
struct file *file;
int ret;
@@ -1010,15 +1036,22 @@ int kernel_read_file_from_path(const char *path, void **buf, loff_t *size,
if (IS_ERR(file))
return PTR_ERR(file);
- ret = kernel_read_file(file, buf, size, max_size, id);
+ ret = kernel_pread_file(file, buf, size, max_size, pos, id);
fput(file);
return ret;
}
+
+int kernel_read_file_from_path(const char *path, void **buf, loff_t *size,
+ loff_t max_size, enum kernel_read_file_id id)
+{
+ return kernel_pread_file_from_path(path, buf, size, max_size, 0, id);
+}
EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
-int kernel_read_file_from_path_initns(const char *path, void **buf,
- loff_t *size, loff_t max_size,
- enum kernel_read_file_id id)
+int kernel_pread_file_from_path_initns(const char *path, void **buf,
+ loff_t *size,
+ loff_t max_size, loff_t pos,
+ enum kernel_read_file_id id)
{
struct file *file;
struct path root;
@@ -1036,14 +1069,22 @@ int kernel_read_file_from_path_initns(const char *path, void **buf,
if (IS_ERR(file))
return PTR_ERR(file);
- ret = kernel_read_file(file, buf, size, max_size, id);
+ ret = kernel_pread_file(file, buf, size, max_size, pos, id);
fput(file);
return ret;
}
+
+int kernel_read_file_from_path_initns(const char *path, void **buf,
+ loff_t *size, loff_t max_size,
+ enum kernel_read_file_id id)
+{
+ return kernel_pread_file_from_path_initns(path, buf, size, max_size, 0, id);
+}
EXPORT_SYMBOL_GPL(kernel_read_file_from_path_initns);
-int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size,
- enum kernel_read_file_id id)
+int kernel_pread_file_from_fd(int fd, void **buf, loff_t *size,
+ loff_t max_size, loff_t pos,
+ enum kernel_read_file_id id)
{
struct fd f = fdget(fd);
int ret = -EBADF;
@@ -1051,11 +1092,17 @@ int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size,
if (!f.file)
goto out;
- ret = kernel_read_file(f.file, buf, size, max_size, id);
+ ret = kernel_pread_file(f.file, buf, size, max_size, pos, id);
out:
fdput(f);
return ret;
}
+
+int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size,
+ enum kernel_read_file_id id)
+{
+ return kernel_pread_file_from_fd(fd, buf, size, max_size, 0, id);
+}
EXPORT_SYMBOL_GPL(kernel_read_file_from_fd);
#if defined(CONFIG_HAVE_AOUT) || defined(CONFIG_BINFMT_FLAT) || \
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 951862b1211b..ab715559cf3c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3012,6 +3012,7 @@ extern int do_pipe_flags(int *, int);
#define __kernel_read_file_id(id) \
id(UNKNOWN, unknown) \
id(FIRMWARE, firmware) \
+ id(FIRMWARE_PARTIAL_READ, firmware) \
id(FIRMWARE_PREALLOC_BUFFER, firmware) \
id(FIRMWARE_EFI_EMBEDDED, firmware) \
id(MODULE, kernel-module) \
@@ -3040,12 +3041,26 @@ static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id)
return kernel_read_file_str[id];
}
+int kernel_pread_file(struct file *file, void **buf, loff_t *size,
+ loff_t pos, loff_t max_size,
+ enum kernel_read_file_id id);
extern int kernel_read_file(struct file *, void **, loff_t *, loff_t,
enum kernel_read_file_id);
+int kernel_pread_file_from_path(const char *path, void **buf,
+ loff_t *size, loff_t pos,
+ loff_t max_size,
+ enum kernel_read_file_id id);
extern int kernel_read_file_from_path(const char *, void **, loff_t *, loff_t,
enum kernel_read_file_id);
+int kernel_pread_file_from_path_initns(const char *path, void **buf,
+ loff_t *size, loff_t pos,
+ loff_t max_size,
+ enum kernel_read_file_id id);
extern int kernel_read_file_from_path_initns(const char *, void **, loff_t *, loff_t,
enum kernel_read_file_id);
+int kernel_pread_file_from_fd(int fd, void **buf, loff_t *size,
+ loff_t pos, loff_t max_size,
+ enum kernel_read_file_id id);
extern int kernel_read_file_from_fd(int, void **, loff_t *, loff_t,
enum kernel_read_file_id);
extern ssize_t kernel_read(struct file *, void *, size_t, loff_t *);
--
2.17.1
next prev parent reply other threads:[~2020-06-09 22:57 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-09 22:56 [PATCH v8 0/8] firmware: add request_partial_firmware_into_buf Scott Branden
2020-06-09 22:56 ` Scott Branden [this message]
2020-06-09 22:56 ` [PATCH v8 2/8] firmware: add offset to request_firmware_into_buf Scott Branden
2020-06-09 22:56 ` [PATCH v8 3/8] test_firmware: add partial read support for request_firmware_into_buf Scott Branden
2020-06-09 22:56 ` [PATCH v8 4/8] firmware: test partial file reads of request_firmware_into_buf Scott Branden
2020-06-09 22:56 ` [PATCH v8 5/8] bcm-vk: add bcm_vk UAPI Scott Branden
2020-06-09 22:56 ` [PATCH v8 7/8] MAINTAINERS: bcm-vk: add maintainer for Broadcom VK Driver Scott Branden
2020-06-09 22:56 ` [PATCH v8 8/8] ima: add FIRMWARE_PARTIAL_READ support Scott Branden
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200609225656.18663-2-scott.branden@broadcom.com \
--to=scott.branden@broadcom.com \
--cc=agross@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=arnd@arndb.de \
--cc=bcm-kernel-feedback-list@broadcom.com \
--cc=bjorn.andersson@linaro.org \
--cc=colin.king@canonical.com \
--cc=dan.carpenter@oracle.com \
--cc=david.brown@linaro.org \
--cc=gregkh@linuxfoundation.org \
--cc=keescook@chromium.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-integrity@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=mcgrof@kernel.org \
--cc=olof@lixom.net \
--cc=rafael@kernel.org \
--cc=shuah@kernel.org \
--cc=skhan@linuxfoundation.org \
--cc=tiwai@suse.de \
--cc=viro@zeniv.linux.org.uk \
--cc=wsa@kernel.org \
--cc=zohar@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).