WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Clean up segment selector fixup and validation.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Clean up segment selector fixup and validation.
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 23 Feb 2006 18:32:07 +0000
Delivery-date: Thu, 23 Feb 2006 18:32:23 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID f84d5cdd9895206af83fbe7798f026b140e7b68f
# Parent  4f4625f805288891106421ea185a02f95dd9c530
Clean up segment selector fixup and validation.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 4f4625f80528 -r f84d5cdd9895 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Thu Feb 23 10:59:27 2006
+++ b/xen/arch/x86/domain.c     Thu Feb 23 13:43:45 2006
@@ -349,27 +349,19 @@
     unsigned long phys_basetab = INVALID_MFN;
     int i, rc;
 
-    /*
-     * This is sufficient! If the descriptor DPL differs from CS RPL then we'll
-     * #GP. If DS, ES, FS, GS are DPL 0 then they'll be cleared automatically.
-     * If SS RPL or DPL differs from CS RPL then we'll #GP.
-     */
     if ( !(c->flags & VGCF_HVM_GUEST) )
     {
-        if ( !VALID_STACKSEL(c->user_regs.ss) ||
-             !VALID_STACKSEL(c->kernel_ss) ||
-             !VALID_CODESEL(c->user_regs.cs) )
-            return -EINVAL;
+        fixup_guest_selector(c->user_regs.ss);
+        fixup_guest_selector(c->kernel_ss);
+        fixup_guest_selector(c->user_regs.cs);
 
 #ifdef __i386__
-        if ( !VALID_CODESEL(c->event_callback_cs) ||
-             !VALID_CODESEL(c->failsafe_callback_cs) )
-            return -EINVAL;
+        fixup_guest_selector(c->event_callback_cs);
+        fixup_guest_selector(c->failsafe_callback_cs);
 #endif
 
         for ( i = 0; i < 256; i++ )
-            if ( !VALID_CODESEL(c->trap_ctxt[i].cs) )
-                return -EINVAL;
+            fixup_guest_selector(c->trap_ctxt[i].cs);
     }
     else if ( !hvm_enabled )
       return -EINVAL;
@@ -383,6 +375,7 @@
         v->arch.flags |= TF_kernel_mode;
 
     memcpy(&v->arch.guest_context, c, sizeof(*c));
+    init_int80_direct_trap(v);
 
     if ( !(c->flags & VGCF_HVM_GUEST) )
     {
diff -r 4f4625f80528 -r f84d5cdd9895 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Thu Feb 23 10:59:27 2006
+++ b/xen/arch/x86/traps.c      Thu Feb 23 13:43:45 2006
@@ -1430,11 +1430,7 @@
         if ( cur.address == 0 )
             break;
 
-        if ( !VALID_CODESEL(cur.cs) )
-        {
-            rc = -EPERM;
-            break;
-        }
+        fixup_guest_selector(cur.cs);
 
         memcpy(&dst[cur.vector], &cur, sizeof(cur));
 
diff -r 4f4625f80528 -r f84d5cdd9895 xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c  Thu Feb 23 10:59:27 2006
+++ b/xen/arch/x86/x86_32/mm.c  Thu Feb 23 13:43:45 2006
@@ -223,8 +223,7 @@
     int nr = smp_processor_id();
     struct tss_struct *t = &init_tss[nr];
 
-    if ( !VALID_STACKSEL(ss) )
-        return -EPERM;
+    fixup_guest_selector(ss);
 
     current->arch.guest_context.kernel_ss = ss;
     current->arch.guest_context.kernel_sp = esp;
@@ -239,7 +238,7 @@
 {
     unsigned long base, limit;
     u32 a = d->a, b = d->b;
-    u16 cs = a>>16;
+    u16 cs;
 
     /* A not-present descriptor will always fault, so is safe. */
     if ( !(b & _SEGMENT_P) ) 
@@ -272,17 +271,12 @@
         if ( (b & _SEGMENT_TYPE) != 0xc00 )
             goto bad;
 
-        /* Can't allow far jump to a Xen-private segment. */
-        if ( !VALID_CODESEL(cs) )
+        /* Validate and fix up the target code selector. */
+        cs = a >> 16;
+        fixup_guest_selector(cs);
+        if ( !guest_gate_selector_okay(cs) )
             goto bad;
-
-        /*
-         * VALID_CODESEL might have fixed up the RPL for us. So be sure to
-         * update the descriptor.
-         *
-         */
-        d->a &= 0x0000ffff;
-        d->a |= cs<<16;
+        a = d->a = (d->a & 0xffffU) | (cs << 16);
 
         /* Reserved bits must be zero. */
         if ( (b & 0xe0) != 0 )
diff -r 4f4625f80528 -r f84d5cdd9895 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c       Thu Feb 23 10:59:27 2006
+++ b/xen/arch/x86/x86_32/traps.c       Thu Feb 23 13:43:45 2006
@@ -254,10 +254,14 @@
 
     /*
      * We can't virtualise interrupt gates, as there's no way to get
-     * the CPU to automatically clear the events_mask variable.
-     */
-    if ( TI_GET_IF(ti) )
+     * the CPU to automatically clear the events_mask variable. Also we
+     * must ensure that the CS is safe to poke into an interrupt gate.
+     */
+    if ( TI_GET_IF(ti) || !guest_gate_selector_okay(ti->cs) )
+    {
+        v->arch.int80_desc.a = v->arch.int80_desc.b = 0;
         return;
+    }
 
     v->arch.int80_desc.a = (ti->cs << 16) | (ti->address & 0xffff);
     v->arch.int80_desc.b =
@@ -274,8 +278,8 @@
 {
     struct vcpu *d = current;
 
-    if ( !VALID_CODESEL(event_selector) || !VALID_CODESEL(failsafe_selector) )
-        return -EPERM;
+    fixup_guest_selector(event_selector);
+    fixup_guest_selector(failsafe_selector);
 
     d->arch.guest_context.event_callback_cs     = event_selector;
     d->arch.guest_context.event_callback_eip    = event_address;
diff -r 4f4625f80528 -r f84d5cdd9895 xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c  Thu Feb 23 10:59:27 2006
+++ b/xen/arch/x86/x86_64/mm.c  Thu Feb 23 13:43:45 2006
@@ -292,7 +292,7 @@
 int check_descriptor(struct desc_struct *d)
 {
     u32 a = d->a, b = d->b;
-    u16 cs = a>>16;
+    u16 cs;
 
     /* A not-present descriptor will always fault, so is safe. */
     if ( !(b & _SEGMENT_P) ) 
@@ -314,17 +314,12 @@
     if ( (b & _SEGMENT_TYPE) != 0xc00 )
         goto bad;
 
-    /* Can't allow far jump to a Xen-private segment. */
-    if ( !VALID_CODESEL(cs) )
+    /* Validate and fix up the target code selector. */
+    cs = a >> 16;
+    fixup_guest_selector(cs);
+    if ( !guest_gate_selector_okay(cs) )
         goto bad;
-
-    /*
-     * VALID_CODESEL might have fixed up the RPL for us. So be sure to
-     * update the descriptor.
-     *
-     */
-    d->a &= 0x0000ffff;
-    d->a |= cs<<16;
+    a = d->a = (d->a & 0xffffU) | (cs << 16);
 
     /* Reserved bits must be zero. */
     if ( (b & 0xe0) != 0 )
diff -r 4f4625f80528 -r f84d5cdd9895 xen/common/elf.c
--- a/xen/common/elf.c  Thu Feb 23 10:59:27 2006
+++ b/xen/common/elf.c  Thu Feb 23 13:43:45 2006
@@ -61,7 +61,6 @@
             continue;
 
         guestinfo = elfbase + shdr->sh_offset;
-        printk("Xen-ELF header found: '%s'\n", guestinfo);
 
         if ( (strstr(guestinfo, "LOADER=generic") == NULL) &&
              (strstr(guestinfo, "GUEST_OS=linux") == NULL) )
diff -r 4f4625f80528 -r f84d5cdd9895 xen/include/asm-x86/desc.h
--- a/xen/include/asm-x86/desc.h        Thu Feb 23 10:59:27 2006
+++ b/xen/include/asm-x86/desc.h        Thu Feb 23 13:43:45 2006
@@ -26,23 +26,28 @@
 #define GUEST_KERNEL_RPL 1
 #endif
 
+/* Fix up the RPL of a guest segment selector. */
+#define fixup_guest_selector(sel)                               \
+    ((sel) = (((sel) & 3) >= GUEST_KERNEL_RPL) ? (sel) :        \
+     (((sel) & ~3) | GUEST_KERNEL_RPL))
+
 /*
- * Guest OS must provide its own code selectors, or use the one we provide. Any
- * LDT selector value is okay. Note that checking only the RPL is insufficient:
- * if the selector is poked into an interrupt, trap or call gate then the RPL
- * is ignored when the gate is accessed.
+ * We need this function because enforcing the correct guest kernel RPL is
+ * unsufficient if the selector is poked into an interrupt, trap or call gate.
+ * The selector RPL is ignored when a gate is accessed. We must therefore make
+ * sure that the selector does not reference a Xen-private segment.
+ * 
+ * Note that selectors used only by IRET do not need to be checked. If the
+ * descriptor DPL fiffers from CS RPL then we'll #GP.
+ * 
+ * Stack and data selectors do not need to be checked. If DS, ES, FS, GS are
+ * DPL < CPL then they'll be cleared automatically. If SS RPL or DPL differs
+ * from CS RPL then we'll #GP.
  */
-#define VALID_SEL(_s)                                                      \
-    (((((_s)>>3) < FIRST_RESERVED_GDT_ENTRY) || ((_s)&4)) &&               \
-     (((_s)&3) == GUEST_KERNEL_RPL))
-#define VALID_CODESEL(_s) ({                                               \
-    if ( ((_s) & 3) == 0 )                                                 \
-        (_s) |= GUEST_KERNEL_RPL;                                          \
-    (_s) == FLAT_KERNEL_CS || VALID_SEL(_s); })
-#define VALID_STACKSEL(_s) ({                                              \
-    if ( ((_s) & 3) == 0 )                                                 \
-        (_s) |= GUEST_KERNEL_RPL;                                          \
-    (_s) == FLAT_KERNEL_SS || VALID_SEL(_s); })
+#define guest_gate_selector_okay(sel)                                   \
+    ((((sel)>>3) < FIRST_RESERVED_GDT_ENTRY) || /* Guest seg? */        \
+     ((sel) == FLAT_KERNEL_CS) ||               /* Xen default seg? */  \
+     ((sel) & 4))                               /* LDT seg? */
 
 /* These are bitmasks for the high 32 bits of a descriptor table entry. */
 #define _SEGMENT_TYPE    (15<< 8)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Clean up segment selector fixup and validation., Xen patchbot -unstable <=