summaryrefslogtreecommitdiffstats
path: root/kernel/kexec_file.c
diff options
context:
space:
mode:
authorMimi Zohar <zohar@linux.vnet.ibm.com>2016-01-14 20:59:14 -0500
committerMimi Zohar <zohar@linux.vnet.ibm.com>2016-02-21 09:06:14 -0500
commitb804defe4297157a9ff45863769efe9a01953398 (patch)
tree562c479b3b93e922ac99a0afe94d09015e3cf11d /kernel/kexec_file.c
parentc6af8efe97d87fa308eb1bbd0cf4feb820a4d622 (diff)
kexec: replace call to copy_file_from_fd() with kernel version
Replace copy_file_from_fd() with kernel_read_file_from_fd(). Two new identifiers named READING_KEXEC_IMAGE and READING_KEXEC_INITRAMFS are defined for measuring, appraising or auditing the kexec image and initramfs. Changelog v3: - return -EBADF, not -ENOEXEC - identifier change - split patch, moving copy_file_from_fd() to a separate patch - split patch, moving IMA changes to a separate patch v0: - use kstat file size type loff_t, not size_t - Calculate the file hash from the in memory buffer - Dave Young Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Acked-by: Kees Cook <keescook@chromium.org> Acked-by: Luis R. Rodriguez <mcgrof@kernel.org> Cc: Eric Biederman <ebiederm@xmission.com> Acked-by: Dave Young <dyoung@redhat.com>
Diffstat (limited to 'kernel/kexec_file.c')
-rw-r--r--kernel/kexec_file.c73
1 files changed, 9 insertions, 64 deletions
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 007b791f676d..b696c3f3708f 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -18,6 +18,7 @@
18#include <linux/kexec.h> 18#include <linux/kexec.h>
19#include <linux/mutex.h> 19#include <linux/mutex.h>
20#include <linux/list.h> 20#include <linux/list.h>
21#include <linux/fs.h>
21#include <crypto/hash.h> 22#include <crypto/hash.h>
22#include <crypto/sha.h> 23#include <crypto/sha.h>
23#include <linux/syscalls.h> 24#include <linux/syscalls.h>
@@ -33,65 +34,6 @@ size_t __weak kexec_purgatory_size = 0;
33 34
34static int kexec_calculate_store_digests(struct kimage *image); 35static int kexec_calculate_store_digests(struct kimage *image);
35 36
36static int copy_file_from_fd(int fd, void **buf, unsigned long *buf_len)
37{
38 struct fd f = fdget(fd);
39 int ret;
40 struct kstat stat;
41 loff_t pos;
42 ssize_t bytes = 0;
43
44 if (!f.file)
45 return -EBADF;
46
47 ret = vfs_getattr(&f.file->f_path, &stat);
48 if (ret)
49 goto out;
50
51 if (stat.size > INT_MAX) {
52 ret = -EFBIG;
53 goto out;
54 }
55
56 /* Don't hand 0 to vmalloc, it whines. */
57 if (stat.size == 0) {
58 ret = -EINVAL;
59 goto out;
60 }
61
62 *buf = vmalloc(stat.size);
63 if (!*buf) {
64 ret = -ENOMEM;
65 goto out;
66 }
67
68 pos = 0;
69 while (pos < stat.size) {
70 bytes = kernel_read(f.file, pos, (char *)(*buf) + pos,
71 stat.size - pos);
72 if (bytes < 0) {
73 vfree(*buf);
74 ret = bytes;
75 goto out;
76 }
77
78 if (bytes == 0)
79 break;
80 pos += bytes;
81 }
82
83 if (pos != stat.size) {
84 ret = -EBADF;
85 vfree(*buf);
86 goto out;
87 }
88
89 *buf_len = pos;
90out:
91 fdput(f);
92 return ret;
93}
94
95/* Architectures can provide this probe function */ 37/* Architectures can provide this probe function */
96int __weak arch_kexec_kernel_image_probe(struct kimage *image, void *buf, 38int __weak arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
97 unsigned long buf_len) 39 unsigned long buf_len)
@@ -182,16 +124,17 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
182{ 124{
183 int ret = 0; 125 int ret = 0;
184 void *ldata; 126 void *ldata;
127 loff_t size;
185 128
186 ret = copy_file_from_fd(kernel_fd, &image->kernel_buf, 129 ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf,
187 &image->kernel_buf_len); 130 &size, INT_MAX, READING_KEXEC_IMAGE);
188 if (ret) 131 if (ret)
189 return ret; 132 return ret;
133 image->kernel_buf_len = size;
190 134
191 /* Call arch image probe handlers */ 135 /* Call arch image probe handlers */
192 ret = arch_kexec_kernel_image_probe(image, image->kernel_buf, 136 ret = arch_kexec_kernel_image_probe(image, image->kernel_buf,
193 image->kernel_buf_len); 137 image->kernel_buf_len);
194
195 if (ret) 138 if (ret)
196 goto out; 139 goto out;
197 140
@@ -206,10 +149,12 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
206#endif 149#endif
207 /* It is possible that there no initramfs is being loaded */ 150 /* It is possible that there no initramfs is being loaded */
208 if (!(flags & KEXEC_FILE_NO_INITRAMFS)) { 151 if (!(flags & KEXEC_FILE_NO_INITRAMFS)) {
209 ret = copy_file_from_fd(initrd_fd, &image->initrd_buf, 152 ret = kernel_read_file_from_fd(initrd_fd, &image->initrd_buf,
210 &image->initrd_buf_len); 153 &size, INT_MAX,
154 READING_KEXEC_INITRAMFS);
211 if (ret) 155 if (ret)
212 goto out; 156 goto out;
157 image->initrd_buf_len = size;
213 } 158 }
214 159
215 if (cmdline_len) { 160 if (cmdline_len) {