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] [IA64] Check privilege level for pal/sal/efi calls.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [IA64] Check privilege level for pal/sal/efi calls.
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 23 Mar 2006 00:52:09 +0000
Delivery-date: Thu, 23 Mar 2006 00:54:03 +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 awilliam@xxxxxxxxxxx
# Node ID 1dc45879fa5c925ef73eef76ab07a5b11e28e574
# Parent  ccb437f2ed4e801cd7ecf2d87743b6d68ebe0d01
[IA64] Check privilege level for pal/sal/efi calls.

Previously a user was able to reset the machine.

Signed-off-by: Tristan Gingold <tristan.gingold@xxxxxxxx>

diff -r ccb437f2ed4e -r 1dc45879fa5c xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c     Mon Mar 20 16:53:17 2006
+++ b/xen/arch/ia64/xen/hypercall.c     Mon Mar 20 16:55:32 2006
@@ -66,13 +66,71 @@
        (hypercall_t)do_ni_hypercall            /*  */
        };
 
-int
-ia64_hypercall (struct pt_regs *regs)
+static int
+xen_hypercall (struct pt_regs *regs)
+{
+       switch (regs->r2) {
+           case __HYPERVISOR_dom0_op:
+               regs->r8 = do_dom0_op(guest_handle_from_ptr(regs->r14,
+                                                           dom0_op_t));
+               break;
+
+           case __HYPERVISOR_memory_op:
+               /* we don't handle reservations; just return success */
+               {
+                   struct xen_memory_reservation reservation;
+                   void *arg = (void *) regs->r15;
+
+                   switch(regs->r14) {
+                   case XENMEM_increase_reservation:
+                   case XENMEM_decrease_reservation:
+                       if (copy_from_user(&reservation, arg,
+                               sizeof(reservation)))
+                           regs->r8 = -EFAULT;
+                       else
+                           regs->r8 = reservation.nr_extents;
+                       break;
+                   default:
+                       regs->r8 = do_memory_op((int) regs->r14, 
guest_handle_from_ptr(regs->r15, void));
+                       break;
+                   }
+               }
+               break;
+
+           case __HYPERVISOR_event_channel_op:
+               regs->r8 = do_event_channel_op(guest_handle_from_ptr(regs->r14, 
evtchn_op_t));
+               break;
+
+           case __HYPERVISOR_grant_table_op:
+               regs->r8 = do_grant_table_op((unsigned int) regs->r14, 
guest_handle_from_ptr(regs->r15, void), (unsigned int) regs->r16);
+               break;
+
+           case __HYPERVISOR_console_io:
+               regs->r8 = do_console_io((int) regs->r14, (int) regs->r15, 
guest_handle_from_ptr(regs->r16, char));
+               break;
+
+           case __HYPERVISOR_xen_version:
+               regs->r8 = do_xen_version((int) regs->r14, 
guest_handle_from_ptr(regs->r15, void));
+               break;
+
+           case __HYPERVISOR_multicall:
+               regs->r8 = do_multicall(guest_handle_from_ptr(regs->r14, 
multicall_entry_t), (unsigned int) regs->r15);
+               break;
+
+           default:
+               printf("unknown xen hypercall %lx\n", regs->r2);
+               regs->r8 = do_ni_hypercall();
+       }
+       return 1;
+}
+
+
+static int
+fw_hypercall (struct pt_regs *regs)
 {
        struct vcpu *v = current;
        struct sal_ret_values x;
        unsigned long *tv, *tc;
-       int pi;
 
        switch (regs->r2) {
            case FW_HYPERCALL_PAL_CALL:
@@ -87,6 +145,7 @@
                VCPU(v,pending_interruption) = 1;
 #endif
                if (regs->r28 == PAL_HALT_LIGHT) {
+                       int pi;
 #define SPURIOUS_VECTOR 15
                        pi = vcpu_check_pending_interrupts(v);
                        if (pi != SPURIOUS_VECTOR) {
@@ -165,66 +224,50 @@
                // FIXME: need fixes in efi.h from 2.6.9
                regs->r8 = EFI_UNSUPPORTED;
                break;
-           case 0xffff:
-               regs->r8 = dump_privop_counts_to_user(
-                       (char *) vcpu_get_gr(v,32),
-                       (int) vcpu_get_gr(v,33));
-               break;
-           case 0xfffe:
-               regs->r8 = zero_privop_counts_to_user(
-                       (char *) vcpu_get_gr(v,32),
-                       (int) vcpu_get_gr(v,33));
-               break;
-           case __HYPERVISOR_dom0_op:
-               regs->r8 = do_dom0_op(guest_handle_from_ptr(regs->r14,
-                                                           dom0_op_t));
-               break;
-
-           case __HYPERVISOR_memory_op:
-               /* we don't handle reservations; just return success */
-               {
-                   struct xen_memory_reservation reservation;
-                   void *arg = (void *) regs->r15;
-
-                   switch(regs->r14) {
-                   case XENMEM_increase_reservation:
-                   case XENMEM_decrease_reservation:
-                       if (copy_from_user(&reservation, arg,
-                               sizeof(reservation)))
-                           regs->r8 = -EFAULT;
-                       else
-                           regs->r8 = reservation.nr_extents;
-                       break;
-                   default:
-                       regs->r8 = do_memory_op((int) regs->r14, 
guest_handle_from_ptr(regs->r15, void));
-                       break;
-                   }
-               }
-               break;
-
-           case __HYPERVISOR_event_channel_op:
-               regs->r8 = do_event_channel_op(guest_handle_from_ptr(regs->r14, 
evtchn_op_t));
-               break;
-
-           case __HYPERVISOR_grant_table_op:
-               regs->r8 = do_grant_table_op((unsigned int) regs->r14, 
guest_handle_from_ptr(regs->r15, void), (unsigned int) regs->r16);
-               break;
-
-           case __HYPERVISOR_console_io:
-               regs->r8 = do_console_io((int) regs->r14, (int) regs->r15, 
guest_handle_from_ptr(regs->r16, char));
-               break;
-
-           case __HYPERVISOR_xen_version:
-               regs->r8 = do_xen_version((int) regs->r14, 
guest_handle_from_ptr(regs->r15, void));
-               break;
-
-           case __HYPERVISOR_multicall:
-               regs->r8 = do_multicall(guest_handle_from_ptr(regs->r14, 
multicall_entry_t), (unsigned int) regs->r15);
-               break;
-
            default:
-               printf("unknown hypercall %lx\n", regs->r2);
+               printf("unknown ia64 fw hypercall %lx\n", regs->r2);
                regs->r8 = do_ni_hypercall();
        }
        return 1;
 }
+
+int
+ia64_hypercall (struct pt_regs *regs)
+{
+       struct vcpu *v = current;
+       unsigned long index = regs->r2;
+
+       if (index >= FW_HYPERCALL_FIRST_USER) {
+           switch (index) {
+               case 0xffff:
+                       regs->r8 = dump_privop_counts_to_user(
+                               (char *) vcpu_get_gr(v,32),
+                               (int) vcpu_get_gr(v,33));
+                       break;
+               case 0xfffe:
+                       regs->r8 = zero_privop_counts_to_user(
+                               (char *) vcpu_get_gr(v,32),
+                               (int) vcpu_get_gr(v,33));
+                       break;
+               default:
+                       printf("unknown user xen/ia64 hypercall %lx\n", index);
+                       regs->r8 = do_ni_hypercall();
+           }
+           return 1;
+       }
+       else if (index >= FW_HYPERCALL_FIRST_ARCH) {
+           int privlvl;
+
+           /* Firmware calls are only allowed in kernel.  */
+           privlvl = (regs->cr_ipsr & IA64_PSR_CPL) >> IA64_PSR_CPL0_BIT;
+           if (privlvl != 2) {
+               /* FIXME: Return a better error value ?
+                  Reflextion ? Illegal operation ?  */
+               regs->r8 = -1;
+               return 1;
+           }
+           else
+               return fw_hypercall (regs);
+       } else
+           return xen_hypercall (regs);
+}
diff -r ccb437f2ed4e -r 1dc45879fa5c xen/include/asm-ia64/dom_fw.h
--- a/xen/include/asm-ia64/dom_fw.h     Mon Mar 20 16:53:17 2006
+++ b/xen/include/asm-ia64/dom_fw.h     Mon Mar 20 16:55:32 2006
@@ -119,6 +119,16 @@
 #define FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT_PADDR        
FW_HYPERCALL_PADDR(FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT_INDEX)
 #define FW_HYPERCALL_EFI_RESET_SYSTEM_PADDR            
FW_HYPERCALL_PADDR(FW_HYPERCALL_EFI_RESET_SYSTEM_INDEX)
 
+/* Hypercalls index bellow _FIRST_ARCH are reserved by Xen, while those above
+   are for the architecture.
+   Note: this limit was defined by Xen/ia64 (and not by Xen).²
+     This can be renumbered safely.
+*/
+#define FW_HYPERCALL_FIRST_ARCH                0x300UL
+
+/* Xen/ia64 user hypercalls.  Only used for debugging.  */
+#define FW_HYPERCALL_FIRST_USER                0xff00UL
+
 extern struct ia64_pal_retval xen_pal_emulator(UINT64, u64, u64, u64);
 extern struct sal_ret_values sal_emulator (long index, unsigned long in1, 
unsigned long in2, unsigned long in3, unsigned long in4, unsigned long in5, 
unsigned long in6, unsigned long in7);
 extern struct ia64_pal_retval pal_emulator_static (unsigned long);

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [IA64] Check privilege level for pal/sal/efi calls., Xen patchbot -unstable <=