aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kexec_file.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-03-17 14:33:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-17 14:33:45 -0400
commitbb7aeae3d680c2c777f54274b0270ced0599f33d (patch)
tree4801a103c2b157b5019cf38a19dc67d54bf38453 /kernel/kexec_file.c
parent70477371dc350746d10431d74f0f213a8d59924c (diff)
parent88a1b564a20e371e6be41b39b85673e9c1959491 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security layer updates from James Morris: "There are a bunch of fixes to the TPM, IMA, and Keys code, with minor fixes scattered across the subsystem. IMA now requires signed policy, and that policy is also now measured and appraised" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (67 commits) X.509: Make algo identifiers text instead of enum akcipher: Move the RSA DER encoding check to the crypto layer crypto: Add hash param to pkcs1pad sign-file: fix build with CMS support disabled MAINTAINERS: update tpmdd urls MODSIGN: linux/string.h should be #included to get memcpy() certs: Fix misaligned data in extra certificate list X.509: Handle midnight alternative notation in GeneralizedTime X.509: Support leap seconds Handle ISO 8601 leap seconds and encodings of midnight in mktime64() X.509: Fix leap year handling again PKCS#7: fix unitialized boolean 'want' firmware: change kernel read fail to dev_dbg() KEYS: Use the symbol value for list size, updated by scripts/insert-sys-cert KEYS: Reserve an extra certificate symbol for inserting without recompiling modsign: hide openssl output in silent builds tpm_tis: fix build warning with tpm_tis_resume ima: require signed IMA policy ima: measure and appraise the IMA policy itself ima: load policy using path ...
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 56b18eb1f001..c72d2ff5896e 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) {