Commit f7a4f689 authored by Kees Cook's avatar Kees Cook Committed by Greg Kroah-Hartman
Browse files

fs/kernel_read_file: Remove redundant size argument



In preparation for refactoring kernel_read_file*(), remove the redundant
"size" argument which is not needed: it can be included in the return
code, with callers adjusted. (VFS reads already cannot be larger than
INT_MAX.)

Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Reviewed-by: default avatarMimi Zohar <zohar@linux.ibm.com>
Reviewed-by: default avatarLuis Chamberlain <mcgrof@kernel.org>
Reviewed-by: default avatarJames Morris <jamorris@linux.microsoft.com>
Acked-by: default avatarScott Branden <scott.branden@broadcom.com>
Link: https://lore.kernel.org/r/20201002173828.2099543-6-keescook@chromium.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5287b07f
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -467,7 +467,7 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
					     size_t in_size,
					     const void *in_buffer))
{
	loff_t size;
	size_t size;
	int i, len;
	int rc = -ENOENT;
	char *path;
@@ -499,10 +499,9 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
		fw_priv->size = 0;

		/* load firmware files from the mount namespace of init */
		rc = kernel_read_file_from_path_initns(path, &buffer,
						       &size, msize,
		rc = kernel_read_file_from_path_initns(path, &buffer, msize,
						       READING_FIRMWARE);
		if (rc) {
		if (rc < 0) {
			if (rc != -ENOENT)
				dev_warn(device, "loading %s failed with error %d\n",
					 path, rc);
@@ -511,6 +510,9 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
					 path);
			continue;
		}
		size = rc;
		rc = 0;

		dev_dbg(device, "Loading firmware from %s\n", path);
		if (decompress) {
			dev_dbg(device, "f/w decompressing %s\n",
+9 −11
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
#include <linux/security.h>
#include <linux/vmalloc.h>

int kernel_read_file(struct file *file, void **buf, loff_t *size,
int kernel_read_file(struct file *file, void **buf,
		     loff_t max_size, enum kernel_read_file_id id)
{
	loff_t i_size, pos;
@@ -29,7 +29,7 @@ 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)) {
	if (i_size > INT_MAX || (max_size > 0 && i_size > max_size)) {
		ret = -EFBIG;
		goto out;
	}
@@ -59,8 +59,6 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
	}

	ret = security_kernel_post_read_file(file, *buf, i_size, id);
	if (!ret)
		*size = pos;

out_free:
	if (ret < 0) {
@@ -72,11 +70,11 @@ out_free:

out:
	allow_write_access(file);
	return ret;
	return ret == 0 ? pos : ret;
}
EXPORT_SYMBOL_GPL(kernel_read_file);

int kernel_read_file_from_path(const char *path, void **buf, loff_t *size,
int kernel_read_file_from_path(const char *path, void **buf,
			       loff_t max_size, enum kernel_read_file_id id)
{
	struct file *file;
@@ -89,14 +87,14 @@ 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_read_file(file, buf, max_size, id);
	fput(file);
	return ret;
}
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,
				      loff_t max_size,
				      enum kernel_read_file_id id)
{
	struct file *file;
@@ -115,13 +113,13 @@ 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_read_file(file, buf, max_size, id);
	fput(file);
	return ret;
}
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,
int kernel_read_file_from_fd(int fd, void **buf, loff_t max_size,
			     enum kernel_read_file_id id)
{
	struct fd f = fdget(fd);
@@ -130,7 +128,7 @@ 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_read_file(f.file, buf, max_size, id);
out:
	fdput(f);
	return ret;
+4 −4
Original line number Diff line number Diff line
@@ -36,16 +36,16 @@ static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id)
}

int kernel_read_file(struct file *file,
		     void **buf, loff_t *size, loff_t max_size,
		     void **buf, loff_t max_size,
		     enum kernel_read_file_id id);
int kernel_read_file_from_path(const char *path,
			       void **buf, loff_t *size, loff_t max_size,
			       void **buf, loff_t max_size,
			       enum kernel_read_file_id id);
int kernel_read_file_from_path_initns(const char *path,
				      void **buf, loff_t *size, loff_t max_size,
				      void **buf, loff_t max_size,
				      enum kernel_read_file_id id);
int kernel_read_file_from_fd(int fd,
			     void **buf, loff_t *size, loff_t max_size,
			     void **buf, loff_t max_size,
			     enum kernel_read_file_id id);

#endif /* _LINUX_KERNEL_READ_FILE_H */
+7 −7
Original line number Diff line number Diff line
@@ -220,13 +220,12 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
{
	int ret;
	void *ldata;
	loff_t size;

	ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf,
				       &size, INT_MAX, READING_KEXEC_IMAGE);
	if (ret)
				       INT_MAX, READING_KEXEC_IMAGE);
	if (ret < 0)
		return ret;
	image->kernel_buf_len = size;
	image->kernel_buf_len = ret;

	/* Call arch image probe handlers */
	ret = arch_kexec_kernel_image_probe(image, image->kernel_buf,
@@ -243,11 +242,12 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
	/* It is possible that there no initramfs is being loaded */
	if (!(flags & KEXEC_FILE_NO_INITRAMFS)) {
		ret = kernel_read_file_from_fd(initrd_fd, &image->initrd_buf,
					       &size, INT_MAX,
					       INT_MAX,
					       READING_KEXEC_INITRAMFS);
		if (ret)
		if (ret < 0)
			goto out;
		image->initrd_buf_len = size;
		image->initrd_buf_len = ret;
		ret = 0;
	}

	if (cmdline_len) {
+3 −4
Original line number Diff line number Diff line
@@ -4035,7 +4035,6 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
{
	struct load_info info = { };
	loff_t size;
	void *hdr = NULL;
	int err;

@@ -4049,12 +4048,12 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
		      |MODULE_INIT_IGNORE_VERMAGIC))
		return -EINVAL;

	err = kernel_read_file_from_fd(fd, &hdr, &size, INT_MAX,
	err = kernel_read_file_from_fd(fd, &hdr, INT_MAX,
				       READING_MODULE);
	if (err)
	if (err < 0)
		return err;
	info.hdr = hdr;
	info.len = size;
	info.len = err;

	return load_module(&info, uargs, flags);
}
Loading