Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 39d637af authored by Dmitry Kasatkin's avatar Dmitry Kasatkin Committed by Mimi Zohar
Browse files

vfs: forbid write access when reading a file into memory



This patch is based on top of the "vfs: support for a common kernel file
loader" patch set.  In general when the kernel is reading a file into
memory it does not want anything else writing to it.

The kernel currently only forbids write access to a file being executed.
This patch extends this locking to files being read by the kernel.

Changelog:
- moved function to kernel_read_file() - Mimi
- updated patch description - Mimi

Signed-off-by: default avatarDmitry Kasatkin <dmitry.kasatkin@huawei.com>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: default avatarMimi Zohar <zohar@linux.vnet.ibm.com>
Reviewed-by: default avatarLuis R. Rodriguez <mcgrof@kernel.org>
Acked-by: default avatarKees Cook <keescook@chromium.org>
parent da20dfe6
Loading
Loading
Loading
Loading
+21 −8
Original line number Diff line number Diff line
@@ -850,15 +850,25 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
	if (ret)
		return ret;

	ret = deny_write_access(file);
	if (ret)
		return ret;

	i_size = i_size_read(file_inode(file));
	if (max_size > 0 && i_size > max_size)
		return -EFBIG;
	if (i_size <= 0)
		return -EINVAL;
	if (max_size > 0 && i_size > max_size) {
		ret = -EFBIG;
		goto out;
	}
	if (i_size <= 0) {
		ret = -EINVAL;
		goto out;
	}

	*buf = vmalloc(i_size);
	if (!*buf)
		return -ENOMEM;
	if (!*buf) {
		ret = -ENOMEM;
		goto out;
	}

	pos = 0;
	while (pos < i_size) {
@@ -876,18 +886,21 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,

	if (pos != i_size) {
		ret = -EIO;
		goto out;
		goto out_free;
	}

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

out:
out_free:
	if (ret < 0) {
		vfree(*buf);
		*buf = NULL;
	}

out:
	allow_write_access(file);
	return ret;
}
EXPORT_SYMBOL_GPL(kernel_read_file);