diff options
author | Vivek Goyal <vgoyal@redhat.com> | 2014-08-08 17:25:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-08 18:57:32 -0400 |
commit | dabe78628dd886c4b71971d1d78f1cecc674b760 (patch) | |
tree | cb13f2ed289a5e2f26b8fac89e6c84eac122f2b3 /kernel/kexec.c | |
parent | 7d3e2bca22feb1f4a624009ff6c15e6f724cb4e7 (diff) |
kexec: move segment verification code in a separate function
Previously do_kimage_alloc() will allocate a kimage structure, copy
segment list from user space and then do the segment list sanity
verification.
Break down this function in 3 parts. do_kimage_alloc_init() to do actual
allocation and basic initialization of kimage structure.
copy_user_segment_list() to copy segment list from user space and
sanity_check_segment_list() to verify the sanity of segment list as passed
by user space.
In later patches, I need to only allocate kimage and not copy segment list
from user space. So breaking down in smaller functions enables re-use of
code at other places.
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Michael Kerrisk <mtk.manpages@gmail.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Eric Biederman <ebiederm@xmission.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Matthew Garrett <mjg59@srcf.ucam.org>
Cc: Greg Kroah-Hartman <greg@kroah.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: WANG Chao <chaowang@redhat.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/kexec.c')
-rw-r--r-- | kernel/kexec.c | 182 |
1 files changed, 100 insertions, 82 deletions
diff --git a/kernel/kexec.c b/kernel/kexec.c index c7cc2a00181c..062e5567750e 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
@@ -125,45 +125,27 @@ static struct page *kimage_alloc_page(struct kimage *image, | |||
125 | gfp_t gfp_mask, | 125 | gfp_t gfp_mask, |
126 | unsigned long dest); | 126 | unsigned long dest); |
127 | 127 | ||
128 | static int do_kimage_alloc(struct kimage **rimage, unsigned long entry, | 128 | static int copy_user_segment_list(struct kimage *image, |
129 | unsigned long nr_segments, | 129 | unsigned long nr_segments, |
130 | struct kexec_segment __user *segments) | 130 | struct kexec_segment __user *segments) |
131 | { | 131 | { |
132 | int ret; | ||
132 | size_t segment_bytes; | 133 | size_t segment_bytes; |
133 | struct kimage *image; | ||
134 | unsigned long i; | ||
135 | int result; | ||
136 | |||
137 | /* Allocate a controlling structure */ | ||
138 | result = -ENOMEM; | ||
139 | image = kzalloc(sizeof(*image), GFP_KERNEL); | ||
140 | if (!image) | ||
141 | goto out; | ||
142 | |||
143 | image->head = 0; | ||
144 | image->entry = &image->head; | ||
145 | image->last_entry = &image->head; | ||
146 | image->control_page = ~0; /* By default this does not apply */ | ||
147 | image->start = entry; | ||
148 | image->type = KEXEC_TYPE_DEFAULT; | ||
149 | |||
150 | /* Initialize the list of control pages */ | ||
151 | INIT_LIST_HEAD(&image->control_pages); | ||
152 | |||
153 | /* Initialize the list of destination pages */ | ||
154 | INIT_LIST_HEAD(&image->dest_pages); | ||
155 | |||
156 | /* Initialize the list of unusable pages */ | ||
157 | INIT_LIST_HEAD(&image->unusable_pages); | ||
158 | 134 | ||
159 | /* Read in the segments */ | 135 | /* Read in the segments */ |
160 | image->nr_segments = nr_segments; | 136 | image->nr_segments = nr_segments; |
161 | segment_bytes = nr_segments * sizeof(*segments); | 137 | segment_bytes = nr_segments * sizeof(*segments); |
162 | result = copy_from_user(image->segment, segments, segment_bytes); | 138 | ret = copy_from_user(image->segment, segments, segment_bytes); |
163 | if (result) { | 139 | if (ret) |
164 | result = -EFAULT; | 140 | ret = -EFAULT; |
165 | goto out; | 141 | |
166 | } | 142 | return ret; |
143 | } | ||
144 | |||
145 | static int sanity_check_segment_list(struct kimage *image) | ||
146 | { | ||
147 | int result, i; | ||
148 | unsigned long nr_segments = image->nr_segments; | ||
167 | 149 | ||
168 | /* | 150 | /* |
169 | * Verify we have good destination addresses. The caller is | 151 | * Verify we have good destination addresses. The caller is |
@@ -185,9 +167,9 @@ static int do_kimage_alloc(struct kimage **rimage, unsigned long entry, | |||
185 | mstart = image->segment[i].mem; | 167 | mstart = image->segment[i].mem; |
186 | mend = mstart + image->segment[i].memsz; | 168 | mend = mstart + image->segment[i].memsz; |
187 | if ((mstart & ~PAGE_MASK) || (mend & ~PAGE_MASK)) | 169 | if ((mstart & ~PAGE_MASK) || (mend & ~PAGE_MASK)) |
188 | goto out; | 170 | return result; |
189 | if (mend >= KEXEC_DESTINATION_MEMORY_LIMIT) | 171 | if (mend >= KEXEC_DESTINATION_MEMORY_LIMIT) |
190 | goto out; | 172 | return result; |
191 | } | 173 | } |
192 | 174 | ||
193 | /* Verify our destination addresses do not overlap. | 175 | /* Verify our destination addresses do not overlap. |
@@ -208,7 +190,7 @@ static int do_kimage_alloc(struct kimage **rimage, unsigned long entry, | |||
208 | pend = pstart + image->segment[j].memsz; | 190 | pend = pstart + image->segment[j].memsz; |
209 | /* Do the segments overlap ? */ | 191 | /* Do the segments overlap ? */ |
210 | if ((mend > pstart) && (mstart < pend)) | 192 | if ((mend > pstart) && (mstart < pend)) |
211 | goto out; | 193 | return result; |
212 | } | 194 | } |
213 | } | 195 | } |
214 | 196 | ||
@@ -220,18 +202,61 @@ static int do_kimage_alloc(struct kimage **rimage, unsigned long entry, | |||
220 | result = -EINVAL; | 202 | result = -EINVAL; |
221 | for (i = 0; i < nr_segments; i++) { | 203 | for (i = 0; i < nr_segments; i++) { |
222 | if (image->segment[i].bufsz > image->segment[i].memsz) | 204 | if (image->segment[i].bufsz > image->segment[i].memsz) |
223 | goto out; | 205 | return result; |
224 | } | 206 | } |
225 | 207 | ||
226 | result = 0; | 208 | /* |
227 | out: | 209 | * Verify we have good destination addresses. Normally |
228 | if (result == 0) | 210 | * the caller is responsible for making certain we don't |
229 | *rimage = image; | 211 | * attempt to load the new image into invalid or reserved |
230 | else | 212 | * areas of RAM. But crash kernels are preloaded into a |
231 | kfree(image); | 213 | * reserved area of ram. We must ensure the addresses |
214 | * are in the reserved area otherwise preloading the | ||
215 | * kernel could corrupt things. | ||
216 | */ | ||
232 | 217 | ||
233 | return result; | 218 | if (image->type == KEXEC_TYPE_CRASH) { |
219 | result = -EADDRNOTAVAIL; | ||
220 | for (i = 0; i < nr_segments; i++) { | ||
221 | unsigned long mstart, mend; | ||
234 | 222 | ||
223 | mstart = image->segment[i].mem; | ||
224 | mend = mstart + image->segment[i].memsz - 1; | ||
225 | /* Ensure we are within the crash kernel limits */ | ||
226 | if ((mstart < crashk_res.start) || | ||
227 | (mend > crashk_res.end)) | ||
228 | return result; | ||
229 | } | ||
230 | } | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static struct kimage *do_kimage_alloc_init(void) | ||
236 | { | ||
237 | struct kimage *image; | ||
238 | |||
239 | /* Allocate a controlling structure */ | ||
240 | image = kzalloc(sizeof(*image), GFP_KERNEL); | ||
241 | if (!image) | ||
242 | return NULL; | ||
243 | |||
244 | image->head = 0; | ||
245 | image->entry = &image->head; | ||
246 | image->last_entry = &image->head; | ||
247 | image->control_page = ~0; /* By default this does not apply */ | ||
248 | image->type = KEXEC_TYPE_DEFAULT; | ||
249 | |||
250 | /* Initialize the list of control pages */ | ||
251 | INIT_LIST_HEAD(&image->control_pages); | ||
252 | |||
253 | /* Initialize the list of destination pages */ | ||
254 | INIT_LIST_HEAD(&image->dest_pages); | ||
255 | |||
256 | /* Initialize the list of unusable pages */ | ||
257 | INIT_LIST_HEAD(&image->unusable_pages); | ||
258 | |||
259 | return image; | ||
235 | } | 260 | } |
236 | 261 | ||
237 | static void kimage_free_page_list(struct list_head *list); | 262 | static void kimage_free_page_list(struct list_head *list); |
@@ -244,10 +269,19 @@ static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry, | |||
244 | struct kimage *image; | 269 | struct kimage *image; |
245 | 270 | ||
246 | /* Allocate and initialize a controlling structure */ | 271 | /* Allocate and initialize a controlling structure */ |
247 | image = NULL; | 272 | image = do_kimage_alloc_init(); |
248 | result = do_kimage_alloc(&image, entry, nr_segments, segments); | 273 | if (!image) |
274 | return -ENOMEM; | ||
275 | |||
276 | image->start = entry; | ||
277 | |||
278 | result = copy_user_segment_list(image, nr_segments, segments); | ||
249 | if (result) | 279 | if (result) |
250 | goto out; | 280 | goto out_free_image; |
281 | |||
282 | result = sanity_check_segment_list(image); | ||
283 | if (result) | ||
284 | goto out_free_image; | ||
251 | 285 | ||
252 | /* | 286 | /* |
253 | * Find a location for the control code buffer, and add it | 287 | * Find a location for the control code buffer, and add it |
@@ -259,22 +293,21 @@ static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry, | |||
259 | get_order(KEXEC_CONTROL_PAGE_SIZE)); | 293 | get_order(KEXEC_CONTROL_PAGE_SIZE)); |
260 | if (!image->control_code_page) { | 294 | if (!image->control_code_page) { |
261 | pr_err("Could not allocate control_code_buffer\n"); | 295 | pr_err("Could not allocate control_code_buffer\n"); |
262 | goto out_free; | 296 | goto out_free_image; |
263 | } | 297 | } |
264 | 298 | ||
265 | image->swap_page = kimage_alloc_control_pages(image, 0); | 299 | image->swap_page = kimage_alloc_control_pages(image, 0); |
266 | if (!image->swap_page) { | 300 | if (!image->swap_page) { |
267 | pr_err("Could not allocate swap buffer\n"); | 301 | pr_err("Could not allocate swap buffer\n"); |
268 | goto out_free; | 302 | goto out_free_control_pages; |
269 | } | 303 | } |
270 | 304 | ||
271 | *rimage = image; | 305 | *rimage = image; |
272 | return 0; | 306 | return 0; |
273 | 307 | out_free_control_pages: | |
274 | out_free: | ||
275 | kimage_free_page_list(&image->control_pages); | 308 | kimage_free_page_list(&image->control_pages); |
309 | out_free_image: | ||
276 | kfree(image); | 310 | kfree(image); |
277 | out: | ||
278 | return result; | 311 | return result; |
279 | } | 312 | } |
280 | 313 | ||
@@ -284,19 +317,17 @@ static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry, | |||
284 | { | 317 | { |
285 | int result; | 318 | int result; |
286 | struct kimage *image; | 319 | struct kimage *image; |
287 | unsigned long i; | ||
288 | 320 | ||
289 | image = NULL; | ||
290 | /* Verify we have a valid entry point */ | 321 | /* Verify we have a valid entry point */ |
291 | if ((entry < crashk_res.start) || (entry > crashk_res.end)) { | 322 | if ((entry < crashk_res.start) || (entry > crashk_res.end)) |
292 | result = -EADDRNOTAVAIL; | 323 | return -EADDRNOTAVAIL; |
293 | goto out; | ||
294 | } | ||
295 | 324 | ||
296 | /* Allocate and initialize a controlling structure */ | 325 | /* Allocate and initialize a controlling structure */ |
297 | result = do_kimage_alloc(&image, entry, nr_segments, segments); | 326 | image = do_kimage_alloc_init(); |
298 | if (result) | 327 | if (!image) |
299 | goto out; | 328 | return -ENOMEM; |
329 | |||
330 | image->start = entry; | ||
300 | 331 | ||
301 | /* Enable the special crash kernel control page | 332 | /* Enable the special crash kernel control page |
302 | * allocation policy. | 333 | * allocation policy. |
@@ -304,25 +335,13 @@ static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry, | |||
304 | image->control_page = crashk_res.start; | 335 | image->control_page = crashk_res.start; |
305 | image->type = KEXEC_TYPE_CRASH; | 336 | image->type = KEXEC_TYPE_CRASH; |
306 | 337 | ||
307 | /* | 338 | result = copy_user_segment_list(image, nr_segments, segments); |
308 | * Verify we have good destination addresses. Normally | 339 | if (result) |
309 | * the caller is responsible for making certain we don't | 340 | goto out_free_image; |
310 | * attempt to load the new image into invalid or reserved | ||
311 | * areas of RAM. But crash kernels are preloaded into a | ||
312 | * reserved area of ram. We must ensure the addresses | ||
313 | * are in the reserved area otherwise preloading the | ||
314 | * kernel could corrupt things. | ||
315 | */ | ||
316 | result = -EADDRNOTAVAIL; | ||
317 | for (i = 0; i < nr_segments; i++) { | ||
318 | unsigned long mstart, mend; | ||
319 | 341 | ||
320 | mstart = image->segment[i].mem; | 342 | result = sanity_check_segment_list(image); |
321 | mend = mstart + image->segment[i].memsz - 1; | 343 | if (result) |
322 | /* Ensure we are within the crash kernel limits */ | 344 | goto out_free_image; |
323 | if ((mstart < crashk_res.start) || (mend > crashk_res.end)) | ||
324 | goto out_free; | ||
325 | } | ||
326 | 345 | ||
327 | /* | 346 | /* |
328 | * Find a location for the control code buffer, and add | 347 | * Find a location for the control code buffer, and add |
@@ -334,15 +353,14 @@ static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry, | |||
334 | get_order(KEXEC_CONTROL_PAGE_SIZE)); | 353 | get_order(KEXEC_CONTROL_PAGE_SIZE)); |
335 | if (!image->control_code_page) { | 354 | if (!image->control_code_page) { |
336 | pr_err("Could not allocate control_code_buffer\n"); | 355 | pr_err("Could not allocate control_code_buffer\n"); |
337 | goto out_free; | 356 | goto out_free_image; |
338 | } | 357 | } |
339 | 358 | ||
340 | *rimage = image; | 359 | *rimage = image; |
341 | return 0; | 360 | return 0; |
342 | 361 | ||
343 | out_free: | 362 | out_free_image: |
344 | kfree(image); | 363 | kfree(image); |
345 | out: | ||
346 | return result; | 364 | return result; |
347 | } | 365 | } |
348 | 366 | ||