[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Check the hypercall number in the privcmd hypercall ioctl.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 605672867c0f9b591e941c8f4a05bb39dbe2c96a
# Parent  9b62efbc881a5fdc18b406de0c6f5406083f65d6
Check the hypercall number in the privcmd hypercall ioctl.
We check it is a member of a small set of permitted hypercalls.
Fix libxenstat to not use multicalls (not permitted, and not
need for efficiency in libxenstat).

Based on an original patch by Chris Wright.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
Signed-off-by: Chris Wright <chrisw@xxxxxxxxxxxx>

diff -r 9b62efbc881a -r 605672867c0f 
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Thu Feb  9 
23:00:17 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Thu Feb  9 
23:16:53 2006
@@ -35,6 +35,9 @@
 static struct proc_dir_entry *privcmd_intf;
 static struct proc_dir_entry *capabilities_intf;
 
+#define NR_HYPERCALLS 32
+static DECLARE_BITMAP(hypercall_permission_map, NR_HYPERCALLS);
+
 static int privcmd_ioctl(struct inode *inode, struct file *file,
                          unsigned int cmd, unsigned long data)
 {
@@ -47,6 +50,12 @@
   
                if (copy_from_user(&hypercall, udata, sizeof(hypercall)))
                        return -EFAULT;
+
+               /* Check hypercall number for validity. */
+               if (hypercall.op >= NR_HYPERCALLS)
+                       return -EINVAL;
+               if (!test_bit(hypercall.op, hypercall_permission_map))
+                       return -EINVAL;
 
 #if defined(__i386__)
                __asm__ __volatile__ (
@@ -260,6 +269,15 @@
 
 static int __init privcmd_init(void)
 {
+       /* Set of hypercalls that privileged applications may execute. */
+       set_bit(__HYPERVISOR_acm_op,           hypercall_permission_map);
+       set_bit(__HYPERVISOR_dom0_op,          hypercall_permission_map);
+       set_bit(__HYPERVISOR_event_channel_op, hypercall_permission_map);
+       set_bit(__HYPERVISOR_memory_op,        hypercall_permission_map);
+       set_bit(__HYPERVISOR_mmu_update,       hypercall_permission_map);
+       set_bit(__HYPERVISOR_mmuext_op,        hypercall_permission_map);
+       set_bit(__HYPERVISOR_xen_version,      hypercall_permission_map);
+
        privcmd_intf = create_xen_proc_entry("privcmd", 0400);
        if (privcmd_intf != NULL)
                privcmd_intf->proc_fops = &privcmd_file_ops;
diff -r 9b62efbc881a -r 605672867c0f 
tools/xenstat/libxenstat/src/xen-interface.c
--- a/tools/xenstat/libxenstat/src/xen-interface.c      Thu Feb  9 23:00:17 2006
+++ b/tools/xenstat/libxenstat/src/xen-interface.c      Thu Feb  9 23:16:53 2006
@@ -61,43 +61,40 @@
                                         xen_extraversion_t *ver)
 {
        privcmd_hypercall_t privcmd;
-       multicall_entry_t multicall[2];
        int ret = 0;
 
-       /* set up for doing hypercall */
-       privcmd.op = __HYPERVISOR_multicall;
-       privcmd.arg[0] = (unsigned long)multicall;
-       privcmd.arg[1] = 2;
-
-       /* first one to get xen version number */
-       multicall[0].op = __HYPERVISOR_xen_version;
-       multicall[0].args[0] = (unsigned long)XENVER_version;
-
-       /* second to get xen version flag */
-       multicall[1].op = __HYPERVISOR_xen_version;
-       multicall[1].args[0] = (unsigned long)XENVER_extraversion;
-       multicall[1].args[1] = (unsigned long)ver;
-
-       if (mlock( &privcmd, sizeof(privcmd_hypercall_t)) < 0) {
+       if (mlock(&privcmd, sizeof(privcmd)) < 0) {
                perror("Failed to mlock privcmd structure");
                return -1;
        }
 
-       if (mlock( multicall, sizeof(multicall_entry_t)) < 0) {
-               perror("Failed to mlock multicall_entry structure");
-               munlock( &multicall, sizeof(multicall_entry_t));
-               return -1;
-       }
-
-       if (ioctl( handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd) < 0) {
+       if (mlock(ver, sizeof(*ver)) < 0) {
+               perror("Failed to mlock extraversion structure");
+               munlock(&privcmd, sizeof(privcmd));
+               return -1;
+       }
+
+       privcmd.op = __HYPERVISOR_xen_version;
+       privcmd.arg[0] = (unsigned long)XENVER_version;
+       privcmd.arg[1] = 0;
+
+       *vnum = ioctl(handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd);
+       if (*vnum < 0) {
                perror("Hypercall failed");
                ret = -1;
        }
 
-       *vnum = multicall[0].result;
-
-       munlock( &privcmd, sizeof(privcmd_hypercall_t));
-       munlock( &multicall, sizeof(multicall_entry_t));
+       privcmd.op = __HYPERVISOR_xen_version;
+       privcmd.arg[0] = (unsigned long)XENVER_extraversion;
+       privcmd.arg[1] = (unsigned long)ver;
+
+       if (ioctl(handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd) < 0) {
+               perror("Hypercall failed");
+               ret = -1;
+       }
+
+       munlock(&privcmd, sizeof(privcmd));
+       munlock(ver, sizeof(*ver));
 
        return ret;
 }

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.