|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC v1 2/8] kexec: implement kexec_file_load() for PECOFF+Authenticode files
This change adds to Xen the kexec_file_load() entry point. The
kexec_file_load() is nearly identical to kexec_load(), but with the
added code to handle checking and handling of PECOFF Authenticode
signature verification.
Signed-off-by: Eric DeVolder <eric.devolder@xxxxxxxxxx>
---
xen/common/kexec.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 129 insertions(+), 2 deletions(-)
diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index 44ae95d..b013514 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -33,6 +33,10 @@
#include <compat/kexec.h>
#endif
+#include "ped.h"
+#include "TrustedCert.h"
+int verify_openssl (pecoff_image_t *pe, const uint8_t *TrustedCert, int
TrustedCertSize);
+
bool_t kexecing = FALSE;
/* Memory regions to store the per cpu register state etc. on a crash. */
@@ -1112,6 +1116,126 @@ error:
return ret;
}
+static int kexec_file_load(XEN_GUEST_HANDLE_PARAM(void) uarg)
+{
+ xen_kexec_load_t load;
+ xen_kexec_segment_t *segments;
+ struct kexec_image *kimage = NULL;
+ int ret;
+ int k, numSigned = 0, numPassed = 0;
+
+ if ( copy_from_guest(&load, uarg, 1) )
+ return -EFAULT;
+
+ if ( load.nr_segments >= KEXEC_SEGMENT_MAX )
+ return -EINVAL;
+
+ segments = xmalloc_array(xen_kexec_segment_t, load.nr_segments);
+ if ( segments == NULL )
+ return -ENOMEM;
+
+ if ( copy_from_guest(segments, load.segments.h, load.nr_segments) )
+ {
+ ret = -EFAULT;
+ goto error;
+ }
+
+ /* Handle signature verification of signed segments */
+ for (k = 0; k < load.nr_segments; ++k)
+ {
+ xen_kexec_segment_t *segment = &segments[k];
+ uint8_t *imageBase = NULL;
+ size_t imageSize;
+ pecoff_image_t *pe = NULL;
+ int j; (void)j;
+
+ if (NULL == segment->buf.h.p) continue;
+
+ imageSize = segment->buf_size;
+ imageBase = xmalloc_array(unsigned char, imageSize);
+ if (NULL == imageBase)
+ {
+ printk("Ooops %u\n", (unsigned)imageSize);
+ ret = -ENOMEM;
+ goto error;
+ }
+ if ( copy_from_guest(imageBase, segment->buf.h, segment->buf_size) )
+ {
+ xfree(imageBase);
+ ret = -EFAULT;
+ goto error;
+ }
+
+ /* Handle PECOFF w/ Authenticode, only ... */
+ pe = pecoff_image_decode(imageBase, imageSize);
+ if (pe && pe->iddc.dd && pe->iddc.dd->CertificateTable.VirtualAddress)
+ {
+ ++numSigned;
+ pecoff_setup_verify(pe);
+ ret = verify_openssl(pe, TrustedCert, sizeof(TrustedCert));
+
+ /* if all is well ... */
+ if (1 == ret)
+ {
+ coff_header_t *ch = pe->chc.ch;
+ unsigned x;
+
+ ++numPassed; /* success! */
+
+ /* point to text executable */
+ for (x = 0; x < ch->NumberOfSections; ++x)
+ {
+ pecoff_section_t *s = pe->sectioncs[x].s;
+ if (
+ (s->Name[0] == '.') &&
+ (s->Name[1] == 't') &&
+ (s->Name[2] == 'e') &&
+ (s->Name[3] == 'x') &&
+ (s->Name[4] == 't')
+ )
+ {
+ /* Adjust segment info for proper load */
+ uint8_t *p = (uint8_t *)segment->buf.h.p;
+ /* adjust to point to start of .text */
+ p += s->PointerToRawData;
+ segment->buf.h.p = p;
+ /* adjust size accordingly */
+ segment->buf_size -= s->PointerToRawData;
+ }
+ }
+ }
+ }
+ if (pe) pecoff_image_free(pe);
+ if (imageBase) xfree(imageBase);
+ }
+ printk("KEXEC_file_load signed %d passed %d\n", numSigned, numPassed);
+
+ if (! ((numPassed == numSigned) && (numSigned > 0)) )
+ ret = -ENOEXEC;
+ else
+ ret = kimage_alloc(&kimage, load.type, load.arch, load.entry_maddr,
+ load.nr_segments, segments);
+
+ if ( ret < 0 )
+ goto error;
+
+ ret = kimage_load_segments(kimage);
+ if ( ret < 0 )
+ goto error;
+
+ ret = kexec_load_slot(kimage);
+ if ( ret < 0 )
+ goto error;
+
+ return 0;
+
+error:
+ if ( ! kimage )
+ xfree(segments);
+ kimage_free(kimage);
+ return ret;
+}
+
static int kexec_do_unload(xen_kexec_unload_t *unload)
{
struct kexec_image *old_kimage;
@@ -1237,8 +1361,11 @@ static int do_kexec_op_internal(unsigned long op,
ret = kexec_unload(uarg);
break;
case KEXEC_CMD_kexec_status:
- ret = kexec_status(uarg);
- break;
+ ret = kexec_status(uarg);
+ break;
+ case KEXEC_CMD_kexec_file_load:
+ ret = kexec_file_load(uarg);
+ break;
}
spin_unlock(&kexec_op_spinlock);
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |