ia64/xen-unstable

changeset 8820:605672867c0f

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@xensource.com>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
author kaf24@firebug.cl.cam.ac.uk
date Fri Feb 10 00:16:53 2006 +0100 (2006-02-10)
parents 9b62efbc881a
children d1596fc2cbaa
files linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c tools/xenstat/libxenstat/src/xen-interface.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Fri Feb 10 00:00:17 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Fri Feb 10 00:16:53 2006 +0100
     1.3 @@ -35,6 +35,9 @@
     1.4  static struct proc_dir_entry *privcmd_intf;
     1.5  static struct proc_dir_entry *capabilities_intf;
     1.6  
     1.7 +#define NR_HYPERCALLS 32
     1.8 +static DECLARE_BITMAP(hypercall_permission_map, NR_HYPERCALLS);
     1.9 +
    1.10  static int privcmd_ioctl(struct inode *inode, struct file *file,
    1.11                           unsigned int cmd, unsigned long data)
    1.12  {
    1.13 @@ -48,6 +51,12 @@ static int privcmd_ioctl(struct inode *i
    1.14  		if (copy_from_user(&hypercall, udata, sizeof(hypercall)))
    1.15  			return -EFAULT;
    1.16  
    1.17 +		/* Check hypercall number for validity. */
    1.18 +		if (hypercall.op >= NR_HYPERCALLS)
    1.19 +			return -EINVAL;
    1.20 +		if (!test_bit(hypercall.op, hypercall_permission_map))
    1.21 +			return -EINVAL;
    1.22 +
    1.23  #if defined(__i386__)
    1.24  		__asm__ __volatile__ (
    1.25  			"pushl %%ebx; pushl %%ecx; pushl %%edx; "
    1.26 @@ -260,6 +269,15 @@ static int capabilities_read(char *page,
    1.27  
    1.28  static int __init privcmd_init(void)
    1.29  {
    1.30 +	/* Set of hypercalls that privileged applications may execute. */
    1.31 +	set_bit(__HYPERVISOR_acm_op,           hypercall_permission_map);
    1.32 +	set_bit(__HYPERVISOR_dom0_op,          hypercall_permission_map);
    1.33 +	set_bit(__HYPERVISOR_event_channel_op, hypercall_permission_map);
    1.34 +	set_bit(__HYPERVISOR_memory_op,        hypercall_permission_map);
    1.35 +	set_bit(__HYPERVISOR_mmu_update,       hypercall_permission_map);
    1.36 +	set_bit(__HYPERVISOR_mmuext_op,        hypercall_permission_map);
    1.37 +	set_bit(__HYPERVISOR_xen_version,      hypercall_permission_map);
    1.38 +
    1.39  	privcmd_intf = create_xen_proc_entry("privcmd", 0400);
    1.40  	if (privcmd_intf != NULL)
    1.41  		privcmd_intf->proc_fops = &privcmd_file_ops;
     2.1 --- a/tools/xenstat/libxenstat/src/xen-interface.c	Fri Feb 10 00:00:17 2006 +0100
     2.2 +++ b/tools/xenstat/libxenstat/src/xen-interface.c	Fri Feb 10 00:16:53 2006 +0100
     2.3 @@ -61,43 +61,40 @@ static int xi_make_xen_version_hypercall
     2.4  					 xen_extraversion_t *ver)
     2.5  {
     2.6  	privcmd_hypercall_t privcmd;
     2.7 -	multicall_entry_t multicall[2];
     2.8  	int ret = 0;
     2.9  
    2.10 -	/* set up for doing hypercall */
    2.11 -	privcmd.op = __HYPERVISOR_multicall;
    2.12 -	privcmd.arg[0] = (unsigned long)multicall;
    2.13 -	privcmd.arg[1] = 2;
    2.14 -
    2.15 -	/* first one to get xen version number */
    2.16 -	multicall[0].op = __HYPERVISOR_xen_version;
    2.17 -	multicall[0].args[0] = (unsigned long)XENVER_version;
    2.18 -
    2.19 -	/* second to get xen version flag */
    2.20 -	multicall[1].op = __HYPERVISOR_xen_version;
    2.21 -	multicall[1].args[0] = (unsigned long)XENVER_extraversion;
    2.22 -	multicall[1].args[1] = (unsigned long)ver;
    2.23 -
    2.24 -	if (mlock( &privcmd, sizeof(privcmd_hypercall_t)) < 0) {
    2.25 +	if (mlock(&privcmd, sizeof(privcmd)) < 0) {
    2.26  		perror("Failed to mlock privcmd structure");
    2.27  		return -1;
    2.28  	}
    2.29  
    2.30 -	if (mlock( multicall, sizeof(multicall_entry_t)) < 0) {
    2.31 -		perror("Failed to mlock multicall_entry structure");
    2.32 -		munlock( &multicall, sizeof(multicall_entry_t));
    2.33 +	if (mlock(ver, sizeof(*ver)) < 0) {
    2.34 +		perror("Failed to mlock extraversion structure");
    2.35 +		munlock(&privcmd, sizeof(privcmd));
    2.36  		return -1;
    2.37  	}
    2.38  
    2.39 -	if (ioctl( handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd) < 0) {
    2.40 +	privcmd.op = __HYPERVISOR_xen_version;
    2.41 +	privcmd.arg[0] = (unsigned long)XENVER_version;
    2.42 +	privcmd.arg[1] = 0;
    2.43 +
    2.44 +	*vnum = ioctl(handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd);
    2.45 +	if (*vnum < 0) {
    2.46  		perror("Hypercall failed");
    2.47  		ret = -1;
    2.48  	}
    2.49  
    2.50 -	*vnum = multicall[0].result;
    2.51 +	privcmd.op = __HYPERVISOR_xen_version;
    2.52 +	privcmd.arg[0] = (unsigned long)XENVER_extraversion;
    2.53 +	privcmd.arg[1] = (unsigned long)ver;
    2.54  
    2.55 -	munlock( &privcmd, sizeof(privcmd_hypercall_t));
    2.56 -	munlock( &multicall, sizeof(multicall_entry_t));
    2.57 +	if (ioctl(handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd) < 0) {
    2.58 +		perror("Hypercall failed");
    2.59 +		ret = -1;
    2.60 +	}
    2.61 +
    2.62 +	munlock(&privcmd, sizeof(privcmd));
    2.63 +	munlock(ver, sizeof(*ver));
    2.64  
    2.65  	return ret;
    2.66  }