1 // SPDX-License-Identifier: GPL-2.0-only
3 #include <linux/fs_struct.h>
4 #include <linux/kernel_read_file.h>
5 #include <linux/security.h>
6 #include <linux/vmalloc.h>
8 int kernel_read_file(struct file *file, void **buf, loff_t *size,
9 loff_t max_size, enum kernel_read_file_id id)
13 void *allocated = NULL;
16 if (!S_ISREG(file_inode(file)->i_mode) || max_size < 0)
19 ret = deny_write_access(file);
23 ret = security_kernel_read_file(file, id);
27 i_size = i_size_read(file_inode(file));
32 if (i_size > SIZE_MAX || (max_size > 0 && i_size > max_size)) {
38 *buf = allocated = vmalloc(i_size);
45 while (pos < i_size) {
46 bytes = kernel_read(file, *buf + pos, i_size - pos, &pos);
61 ret = security_kernel_post_read_file(file, *buf, i_size, id);
74 allow_write_access(file);
77 EXPORT_SYMBOL_GPL(kernel_read_file);
79 int kernel_read_file_from_path(const char *path, void **buf, loff_t *size,
80 loff_t max_size, enum kernel_read_file_id id)
88 file = filp_open(path, O_RDONLY, 0);
92 ret = kernel_read_file(file, buf, size, max_size, id);
96 EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
98 int kernel_read_file_from_path_initns(const char *path, void **buf,
99 loff_t *size, loff_t max_size,
100 enum kernel_read_file_id id)
109 task_lock(&init_task);
110 get_fs_root(init_task.fs, &root);
111 task_unlock(&init_task);
113 file = file_open_root(root.dentry, root.mnt, path, O_RDONLY, 0);
116 return PTR_ERR(file);
118 ret = kernel_read_file(file, buf, size, max_size, id);
122 EXPORT_SYMBOL_GPL(kernel_read_file_from_path_initns);
124 int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size,
125 enum kernel_read_file_id id)
127 struct fd f = fdget(fd);
133 ret = kernel_read_file(f.file, buf, size, max_size, id);
138 EXPORT_SYMBOL_GPL(kernel_read_file_from_fd);