[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |