From: Vivek Goyal <vgoyal@redhat.com>
To: linux-kernel@vger.kernel.org, kexec@lists.infradead.org
Cc: ebiederm@xmission.com, hpa@zytor.com, mjg59@srcf.ucam.org,
greg@kroah.com, bp@alien8.de, jkosina@suse.cz, dyoung@redhat.com,
chaowang@redhat.com, bhe@redhat.com, akpm@linux-foundation.org,
Vivek Goyal <vgoyal@redhat.com>
Subject: [PATCH 03/13] kexec: Move segment verification code in a separate function
Date: Tue, 3 Jun 2014 09:06:52 -0400 [thread overview]
Message-ID: <1401800822-27425-4-git-send-email-vgoyal@redhat.com> (raw)
In-Reply-To: <1401800822-27425-1-git-send-email-vgoyal@redhat.com>
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>
---
kernel/kexec.c | 182 ++++++++++++++++++++++++++++++++-------------------------
1 file changed, 101 insertions(+), 81 deletions(-)
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 28c5706..c435c5f 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -124,45 +124,27 @@ static struct page *kimage_alloc_page(struct kimage *image,
gfp_t gfp_mask,
unsigned long dest);
-static int do_kimage_alloc(struct kimage **rimage, unsigned long entry,
- unsigned long nr_segments,
- struct kexec_segment __user *segments)
+static int copy_user_segment_list(struct kimage *image,
+ unsigned long nr_segments,
+ struct kexec_segment __user *segments)
{
+ int ret;
size_t segment_bytes;
- struct kimage *image;
- unsigned long i;
- int result;
-
- /* Allocate a controlling structure */
- result = -ENOMEM;
- image = kzalloc(sizeof(*image), GFP_KERNEL);
- if (!image)
- goto out;
-
- image->head = 0;
- image->entry = &image->head;
- image->last_entry = &image->head;
- image->control_page = ~0; /* By default this does not apply */
- image->start = entry;
- image->type = KEXEC_TYPE_DEFAULT;
-
- /* Initialize the list of control pages */
- INIT_LIST_HEAD(&image->control_pages);
-
- /* Initialize the list of destination pages */
- INIT_LIST_HEAD(&image->dest_pages);
-
- /* Initialize the list of unusable pages */
- INIT_LIST_HEAD(&image->unuseable_pages);
/* Read in the segments */
image->nr_segments = nr_segments;
segment_bytes = nr_segments * sizeof(*segments);
- result = copy_from_user(image->segment, segments, segment_bytes);
- if (result) {
- result = -EFAULT;
- goto out;
- }
+ ret = copy_from_user(image->segment, segments, segment_bytes);
+ if (ret)
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static int sanity_check_segment_list(struct kimage *image)
+{
+ int result, i;
+ unsigned long nr_segments = image->nr_segments;
/*
* Verify we have good destination addresses. The caller is
@@ -184,9 +166,9 @@ static int do_kimage_alloc(struct kimage **rimage, unsigned long entry,
mstart = image->segment[i].mem;
mend = mstart + image->segment[i].memsz;
if ((mstart & ~PAGE_MASK) || (mend & ~PAGE_MASK))
- goto out;
+ return result;
if (mend >= KEXEC_DESTINATION_MEMORY_LIMIT)
- goto out;
+ return result;
}
/* Verify our destination addresses do not overlap.
@@ -207,7 +189,7 @@ static int do_kimage_alloc(struct kimage **rimage, unsigned long entry,
pend = pstart + image->segment[j].memsz;
/* Do the segments overlap ? */
if ((mend > pstart) && (mstart < pend))
- goto out;
+ return result;
}
}
@@ -219,18 +201,61 @@ static int do_kimage_alloc(struct kimage **rimage, unsigned long entry,
result = -EINVAL;
for (i = 0; i < nr_segments; i++) {
if (image->segment[i].bufsz > image->segment[i].memsz)
- goto out;
+ return result;
}
- result = 0;
-out:
- if (result == 0)
- *rimage = image;
- else
- kfree(image);
+ /*
+ * Verify we have good destination addresses. Normally
+ * the caller is responsible for making certain we don't
+ * attempt to load the new image into invalid or reserved
+ * areas of RAM. But crash kernels are preloaded into a
+ * reserved area of ram. We must ensure the addresses
+ * are in the reserved area otherwise preloading the
+ * kernel could corrupt things.
+ */
- return result;
+ if (image->type == KEXEC_TYPE_CRASH) {
+ result = -EADDRNOTAVAIL;
+ for (i = 0; i < nr_segments; i++) {
+ unsigned long mstart, mend;
+ mstart = image->segment[i].mem;
+ mend = mstart + image->segment[i].memsz - 1;
+ /* Ensure we are within the crash kernel limits */
+ if ((mstart < crashk_res.start) ||
+ (mend > crashk_res.end))
+ return result;
+ }
+ }
+
+ return 0;
+}
+
+static struct kimage *do_kimage_alloc_init(void)
+{
+ struct kimage *image;
+
+ /* Allocate a controlling structure */
+ image = kzalloc(sizeof(*image), GFP_KERNEL);
+ if (!image)
+ return NULL;
+
+ image->head = 0;
+ image->entry = &image->head;
+ image->last_entry = &image->head;
+ image->control_page = ~0; /* By default this does not apply */
+ image->type = KEXEC_TYPE_DEFAULT;
+
+ /* Initialize the list of control pages */
+ INIT_LIST_HEAD(&image->control_pages);
+
+ /* Initialize the list of destination pages */
+ INIT_LIST_HEAD(&image->dest_pages);
+
+ /* Initialize the list of unusable pages */
+ INIT_LIST_HEAD(&image->unuseable_pages);
+
+ return image;
}
static void kimage_free_page_list(struct list_head *list);
@@ -243,10 +268,19 @@ static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry,
struct kimage *image;
/* Allocate and initialize a controlling structure */
- image = NULL;
- result = do_kimage_alloc(&image, entry, nr_segments, segments);
+ image = do_kimage_alloc_init();
+ if (!image)
+ return -ENOMEM;
+
+ image->start = entry;
+
+ result = copy_user_segment_list(image, nr_segments, segments);
if (result)
- goto out;
+ goto out_free_image;
+
+ result = sanity_check_segment_list(image);
+ if (result)
+ goto out_free_image;
/*
* Find a location for the control code buffer, and add it
@@ -258,22 +292,23 @@ static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry,
get_order(KEXEC_CONTROL_PAGE_SIZE));
if (!image->control_code_page) {
printk(KERN_ERR "Could not allocate control_code_buffer\n");
- goto out_free;
+ goto out_free_image;
}
image->swap_page = kimage_alloc_control_pages(image, 0);
if (!image->swap_page) {
printk(KERN_ERR "Could not allocate swap buffer\n");
- goto out_free;
+ goto out_free_control_pages;
}
*rimage = image;
return 0;
-out_free:
+
+out_free_control_pages:
kimage_free_page_list(&image->control_pages);
+out_free_image:
kfree(image);
-out:
return result;
}
@@ -283,19 +318,17 @@ static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry,
{
int result;
struct kimage *image;
- unsigned long i;
- image = NULL;
/* Verify we have a valid entry point */
- if ((entry < crashk_res.start) || (entry > crashk_res.end)) {
- result = -EADDRNOTAVAIL;
- goto out;
- }
+ if ((entry < crashk_res.start) || (entry > crashk_res.end))
+ return -EADDRNOTAVAIL;
/* Allocate and initialize a controlling structure */
- result = do_kimage_alloc(&image, entry, nr_segments, segments);
- if (result)
- goto out;
+ image = do_kimage_alloc_init();
+ if (!image)
+ return -ENOMEM;
+
+ image->start = entry;
/* Enable the special crash kernel control page
* allocation policy.
@@ -303,25 +336,13 @@ static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry,
image->control_page = crashk_res.start;
image->type = KEXEC_TYPE_CRASH;
- /*
- * Verify we have good destination addresses. Normally
- * the caller is responsible for making certain we don't
- * attempt to load the new image into invalid or reserved
- * areas of RAM. But crash kernels are preloaded into a
- * reserved area of ram. We must ensure the addresses
- * are in the reserved area otherwise preloading the
- * kernel could corrupt things.
- */
- result = -EADDRNOTAVAIL;
- for (i = 0; i < nr_segments; i++) {
- unsigned long mstart, mend;
+ result = copy_user_segment_list(image, nr_segments, segments);
+ if (result)
+ goto out_free_image;
- mstart = image->segment[i].mem;
- mend = mstart + image->segment[i].memsz - 1;
- /* Ensure we are within the crash kernel limits */
- if ((mstart < crashk_res.start) || (mend > crashk_res.end))
- goto out_free;
- }
+ result = sanity_check_segment_list(image);
+ if (result)
+ goto out_free_image;
/*
* Find a location for the control code buffer, and add
@@ -333,15 +354,14 @@ static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry,
get_order(KEXEC_CONTROL_PAGE_SIZE));
if (!image->control_code_page) {
printk(KERN_ERR "Could not allocate control_code_buffer\n");
- goto out_free;
+ goto out_free_image;
}
*rimage = image;
return 0;
-out_free:
+out_free_image:
kfree(image);
-out:
return result;
}
--
1.9.0
next prev parent reply other threads:[~2014-06-03 13:08 UTC|newest]
Thread overview: 104+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-03 13:06 [RFC PATCH 00/13][V3] kexec: A new system call to allow in kernel loading Vivek Goyal
2014-06-03 13:06 ` [PATCH 01/13] bin2c: Move bin2c in scripts/basic Vivek Goyal
2014-06-03 16:01 ` Borislav Petkov
2014-06-03 17:13 ` Vivek Goyal
2014-06-03 13:06 ` [PATCH 02/13] kernel: Build bin2c based on config option CONFIG_BUILD_BIN2C Vivek Goyal
2014-06-04 9:13 ` Borislav Petkov
2014-06-03 13:06 ` Vivek Goyal [this message]
2014-06-04 9:32 ` [PATCH 03/13] kexec: Move segment verification code in a separate function Borislav Petkov
2014-06-04 18:47 ` Vivek Goyal
2014-06-04 20:30 ` Borislav Petkov
2014-06-05 14:05 ` Vivek Goyal
2014-06-05 14:07 ` Borislav Petkov
2014-06-03 13:06 ` [PATCH 04/13] resource: Provide new functions to walk through resources Vivek Goyal
2014-06-04 10:24 ` Borislav Petkov
2014-06-05 13:58 ` Vivek Goyal
2014-06-03 13:06 ` [PATCH 05/13] kexec: Make kexec_segment user buffer pointer a union Vivek Goyal
2014-06-04 10:34 ` Borislav Petkov
2014-06-03 13:06 ` [PATCH 06/13] kexec: New syscall kexec_file_load() declaration Vivek Goyal
2014-06-04 15:18 ` Borislav Petkov
2014-06-05 9:56 ` WANG Chao
2014-06-05 15:16 ` Vivek Goyal
2014-06-05 15:22 ` Vivek Goyal
2014-06-06 6:34 ` WANG Chao
2014-06-03 13:06 ` [PATCH 07/13] kexec: Implementation of new syscall kexec_file_load Vivek Goyal
2014-06-05 11:15 ` Borislav Petkov
2014-06-05 20:17 ` Vivek Goyal
2014-06-06 2:11 ` Borislav Petkov
2014-06-06 18:02 ` Vivek Goyal
2014-06-11 14:13 ` Borislav Petkov
2014-06-11 17:04 ` Vivek Goyal
2014-06-06 6:56 ` WANG Chao
2014-06-06 18:19 ` Vivek Goyal
2014-06-09 2:11 ` Dave Young
2014-06-09 5:35 ` WANG Chao
2014-06-09 15:41 ` Vivek Goyal
2014-06-13 7:50 ` Borislav Petkov
2014-06-13 8:00 ` WANG Chao
2014-06-13 8:10 ` Borislav Petkov
2014-06-13 8:24 ` WANG Chao
2014-06-13 8:30 ` Borislav Petkov
2014-06-13 12:49 ` Vivek Goyal
2014-06-13 12:46 ` Vivek Goyal
2014-06-13 15:36 ` Borislav Petkov
2014-06-16 17:38 ` Vivek Goyal
2014-06-16 20:05 ` Borislav Petkov
2014-06-16 20:53 ` Vivek Goyal
2014-06-16 21:09 ` Borislav Petkov
2014-06-16 21:25 ` H. Peter Anvin
2014-06-16 21:43 ` Vivek Goyal
2014-06-16 22:10 ` Borislav Petkov
2014-06-16 22:49 ` H. Peter Anvin
2014-06-09 15:30 ` Vivek Goyal
2014-06-03 13:06 ` [PATCH 08/13] purgatory/sha256: Provide implementation of sha256 in purgaotory context Vivek Goyal
2014-06-03 13:06 ` [PATCH 09/13] purgatory: Core purgatory functionality Vivek Goyal
2014-06-05 20:05 ` Borislav Petkov
2014-06-06 19:51 ` Vivek Goyal
2014-06-13 10:17 ` Borislav Petkov
2014-06-16 17:25 ` Vivek Goyal
2014-06-16 20:10 ` Borislav Petkov
2014-06-03 13:06 ` [PATCH 10/13] kexec: Load and Relocate purgatory at kernel load time Vivek Goyal
2014-06-10 16:31 ` Borislav Petkov
2014-06-11 19:24 ` Vivek Goyal
2014-06-13 16:14 ` Borislav Petkov
2014-06-03 13:07 ` [PATCH 11/13] kexec-bzImage: Support for loading bzImage using 64bit entry Vivek Goyal
2014-06-15 16:35 ` Borislav Petkov
2014-06-15 16:56 ` H. Peter Anvin
2014-06-16 20:06 ` Vivek Goyal
2014-06-16 20:57 ` Borislav Petkov
2014-06-16 21:15 ` Vivek Goyal
2014-06-16 21:27 ` Borislav Petkov
2014-06-16 21:45 ` Vivek Goyal
2014-06-24 17:31 ` Vivek Goyal
2014-06-24 18:23 ` Borislav Petkov
2014-06-03 13:07 ` [PATCH 12/13] kexec: Support for Kexec on panic using new system call Vivek Goyal
2014-06-17 21:43 ` Borislav Petkov
2014-06-18 14:20 ` Vivek Goyal
2014-06-03 13:07 ` [PATCH 13/13] kexec: Support kexec/kdump on EFI systems Vivek Goyal
2014-06-18 15:43 ` Borislav Petkov
2014-06-18 16:06 ` Borislav Petkov
2014-06-18 17:39 ` Vivek Goyal
2014-06-03 13:12 ` [RFC PATCH 00/13][V3] kexec: A new system call to allow in kernel loading Vivek Goyal
2014-06-04 9:22 ` WANG Chao
2014-06-04 17:50 ` Vivek Goyal
2014-06-04 19:39 ` Michael Kerrisk
2014-06-05 14:04 ` Vivek Goyal
2014-06-06 5:45 ` Michael Kerrisk (man-pages)
2014-06-06 18:04 ` Vivek Goyal
2014-06-05 8:31 ` Dave Young
2014-06-05 15:01 ` Vivek Goyal
2014-06-06 7:37 ` Dave Young
2014-06-06 20:04 ` Vivek Goyal
2014-06-09 1:57 ` Dave Young
2014-06-06 20:37 ` H. Peter Anvin
2014-06-06 20:58 ` Matt Fleming
2014-06-06 21:00 ` H. Peter Anvin
2014-06-06 21:02 ` Matt Fleming
2014-06-12 5:42 ` Dave Young
2014-06-12 12:36 ` Vivek Goyal
2014-06-17 14:24 ` Vivek Goyal
2014-06-18 1:45 ` Dave Young
2014-06-18 1:52 ` Dave Young
2014-06-18 12:40 ` Vivek Goyal
2014-06-16 21:13 ` Borislav Petkov
2014-06-17 13:24 ` Vivek Goyal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1401800822-27425-4-git-send-email-vgoyal@redhat.com \
--to=vgoyal@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=bhe@redhat.com \
--cc=bp@alien8.de \
--cc=chaowang@redhat.com \
--cc=dyoung@redhat.com \
--cc=ebiederm@xmission.com \
--cc=greg@kroah.com \
--cc=hpa@zytor.com \
--cc=jkosina@suse.cz \
--cc=kexec@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mjg59@srcf.ucam.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).