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

Re: [Xen-devel] [PATCH] linux/privcmd: fix for proper operation in compat mode



On Tue, Jan 05, 2010 at 12:52:04PM +0000, Jan Beulich wrote:
> - sizeof(struct privcmd_mmapbatch_32) was wrong
> - MFN array must be translated for IOCTL_PRIVCMD_MMAPBATCH
> 
> Also, the error indicator of IOCTL_PRIVCMD_MMAPBATCH should be in the
> top nibble (it is documented that way in include/xen/public/privcmd.h
> and include/xen/compat_ioctl.h), but since that is an incompatible
> change it is not being done here (instead, a new ioctl with proper
> behavior will need to be added).
> 
> As usual, written against 2.6.32.2 and made apply to the 2.6.18
> tree without further testing.
> 
> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
> 
> --- head-2010-01-04.orig/drivers/xen/privcmd/compat_privcmd.c 2009-11-06 
> 10:45:48.000000000 +0100
> +++ head-2010-01-04/drivers/xen/privcmd/compat_privcmd.c      2010-01-04 
> 13:50:00.000000000 +0100
> @@ -51,17 +51,49 @@ int privcmd_ioctl_32(int fd, unsigned in
>               struct privcmd_mmapbatch *p;
>               struct privcmd_mmapbatch_32 *p32;
>               struct privcmd_mmapbatch_32 n32;
> +#ifdef xen_pfn32_t
> +             xen_pfn_t *__user arr;
> +             xen_pfn32_t *__user arr32;
> +             unsigned int i;
> +#endif
>  
>               p32 = compat_ptr(arg);
>               p = compat_alloc_user_space(sizeof(*p));
>               if (copy_from_user(&n32, p32, sizeof(n32)) ||
>                   put_user(n32.num, &p->num) ||
>                   put_user(n32.dom, &p->dom) ||
> -                 put_user(n32.addr, &p->addr) ||
> -                 put_user(compat_ptr(n32.arr), &p->arr))
> +                 put_user(n32.addr, &p->addr))
>                       return -EFAULT;
> +#ifdef xen_pfn32_t
> +             arr = compat_alloc_user_space(n32.num * sizeof(*arr)
> +                                           + sizeof(*p));
> +             arr32 = compat_ptr(n32.arr);
> +             for (i = 0; i < n32.num; ++i) {
> +                     xen_pfn32_t mfn;
> +
> +                     if (get_user(mfn, arr32 + i) || put_user(mfn, arr + i))
> +                             return -EFAULT;
> +             }
> +
> +             if (put_user(arr, &p->arr))
> +                     return -EFAULT;
> +#else
> +             if (put_user(compat_ptr(n32.arr), &p->arr))
> +                     return -EFAULT;
> +#endif
>               
>               ret = sys_ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH, (unsigned long)p);
> +
> +#ifdef xen_pfn32_t
> +             for (i = 0; !ret && i < n32.num; ++i) {
> +                     xen_pfn_t mfn;
> +
> +                     if (get_user(mfn, arr + i) || put_user(mfn, arr32 + i))
> +                             ret = -EFAULT;
> +                     else if (mfn != (xen_pfn32_t)mfn)
> +                             ret = -ERANGE;
> +             }
> +#endif
>       }
>               break;
>       default:

Perhaps this could be refactored to reduce or remove the #ifdefs ?

> --- head-2010-01-04.orig/include/xen/compat_ioctl.h   2007-07-10 
> 09:42:30.000000000 +0200
> +++ head-2010-01-04/include/xen/compat_ioctl.h        2009-12-17 
> 15:40:40.000000000 +0100
> @@ -23,6 +23,11 @@
>  #define __LINUX_XEN_COMPAT_H__ 
>  
>  #include <linux/compat.h>
> +#include <linux/compiler.h>
> +
> +#if defined(CONFIG_X86) || defined(CONFIG_IA64)
> +#define xen_pfn32_t __u32
> +#endif

Is it usual in xen for a type to be a #define in xen?

Ito my mind it would make things a lot clearer to use a #define called
SOME_FEATURE and then either use __u32 directly for the type or
typedef __u32 xen_pfn32_t.

>  
>  extern int privcmd_ioctl_32(int fd, unsigned int cmd, unsigned long arg);
>  struct privcmd_mmap_32 {
> @@ -34,7 +39,14 @@ struct privcmd_mmap_32 {
>  struct privcmd_mmapbatch_32 {
>       int num;     /* number of pages to populate */
>       domid_t dom; /* target domain */
> +#if defined(CONFIG_X86) || defined(CONFIG_IA64)
> +     union {      /* virtual address */
> +             __u64 addr __packed;
> +             __u32 va;
> +     };
> +#else
>       __u64 addr;  /* virtual address */
> +#endif
>       compat_uptr_t arr; /* array of mfns - top nibble set on err */
>  };
>  #define IOCTL_PRIVCMD_MMAP_32                   \

Its unclear to me why va is necessary.
It doesn't seem to be used anywhere in the patch.


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


 


Rackspace

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