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,
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 > INT_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);
72 allow_write_access(file);
73 return ret == 0 ? pos : ret;
75 EXPORT_SYMBOL_GPL(kernel_read_file);
77 int kernel_read_file_from_path(const char *path, void **buf,
78 loff_t max_size, enum kernel_read_file_id id)
86 file = filp_open(path, O_RDONLY, 0);
90 ret = kernel_read_file(file, buf, max_size, id);
94 EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
96 int kernel_read_file_from_path_initns(const char *path, void **buf,
98 enum kernel_read_file_id id)
107 task_lock(&init_task);
108 get_fs_root(init_task.fs, &root);
109 task_unlock(&init_task);
111 file = file_open_root(root.dentry, root.mnt, path, O_RDONLY, 0);
114 return PTR_ERR(file);
116 ret = kernel_read_file(file, buf, max_size, id);
120 EXPORT_SYMBOL_GPL(kernel_read_file_from_path_initns);
122 int kernel_read_file_from_fd(int fd, void **buf, loff_t max_size,
123 enum kernel_read_file_id id)
125 struct fd f = fdget(fd);
131 ret = kernel_read_file(f.file, buf, max_size, id);
136 EXPORT_SYMBOL_GPL(kernel_read_file_from_fd);