[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] xen/privcmd: fix for proper operation in compat mode
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1262767089 0 # Node ID aa133dee7792aeb3d2a1aad90de7aa0d933e427e # Parent 2b2d888e5a804c81dc5a1dcd0de4cf5e83106bf4 xen/privcmd: fix for proper operation in compat mode - 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). Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> --- drivers/xen/privcmd/compat_privcmd.c | 36 +++++++++++++++++++++++++++++++++-- include/xen/compat_ioctl.h | 12 +++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff -r 2b2d888e5a80 -r aa133dee7792 drivers/xen/privcmd/compat_privcmd.c --- a/drivers/xen/privcmd/compat_privcmd.c Wed Jan 06 08:15:35 2010 +0000 +++ b/drivers/xen/privcmd/compat_privcmd.c Wed Jan 06 08:38:09 2010 +0000 @@ -52,17 +52,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: diff -r 2b2d888e5a80 -r aa133dee7792 include/xen/compat_ioctl.h --- a/include/xen/compat_ioctl.h Wed Jan 06 08:15:35 2010 +0000 +++ b/include/xen/compat_ioctl.h Wed Jan 06 08:38:09 2010 +0000 @@ -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 extern int privcmd_ioctl_32(int fd, unsigned int cmd, unsigned long arg); struct privcmd_mmap_32 { @@ -34,7 +39,14 @@ struct privcmd_mmapbatch_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; /* ensures union is 4-byte aligned */ + }; +#else __u64 addr; /* virtual address */ +#endif compat_uptr_t arr; /* array of mfns - top nibble set on err */ }; #define IOCTL_PRIVCMD_MMAP_32 \ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |