# 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
|