From: Arnd Bergmann <arndbergmann@googlemail.com>
To: David Miller <davem@davemloft.net>
Cc: airlied@linux.ie, dri-devel@lists.sourceforge.net,
andi@firstfloor.org, linux-kernel@vger.kernel.org
Subject: Re: is avoiding compat ioctls possible?
Date: Wed, 28 Oct 2009 13:13:32 +0100 [thread overview]
Message-ID: <200910281313.32827.arnd@arndb.de> (raw)
In-Reply-To: <20091028.005342.60092591.davem@davemloft.net>
On Wednesday 28 October 2009, David Miller wrote:
> -/* The two 64-bit arches where alignof(u64)==4 in 32-bit code */
> #if defined (CONFIG_X86_64) || defined(CONFIG_IA64)
> typedef struct drm_radeon_setparam32 {
> int param;
> u64 value;
> } __attribute__((packed)) drm_radeon_setparam32_t;
> +#else
> +#define drm_radeon_setparam32_t drm_radeon_setparam_t
> +#endif
I guess a cleaner way to put this would be
typedef struct drm_radeon_setparam32 {
int param;
compat_u64 value;
} drm_radeon_setparam32_t;
> static int compat_radeon_cp_setparam(struct file *file, unsigned int cmd,
> unsigned long arg)
> {
> drm_radeon_setparam32_t req32;
> drm_radeon_setparam_t __user *request;
> + compat_uptr_t uptr;
>
> if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
> return -EFAULT;
The ioctl argument actually needs a compat_ptr() conversion as well.
For the s390 case, we can't do that in common code, because some
ioctl methods put a 32 bit integer into the argument. Not sure if we
want to fix that everywhere, the problem is very common and the
impact is minimal.
> +static int compat_radeon_info_ioctl(struct file *file, unsigned int cmd,
> + unsigned long arg)
> +{
> + struct drm_radeon_info __user *uinfo;
> + struct drm_radeon_info kinfo;
> + compat_uptr_t uaddr;
> + void *uptr;
> +
> + if (copy_from_user(&kinfo, (void __user *) arg, sizeof(kinfo)))
> + return -EFAULT;
> +
> + uaddr = kinfo.value;
> + uptr = compat_ptr(uaddr);
> + if (kinfo.value == (uint64_t) uptr)
> + return drm_ioctl(file->f_dentry->d_inode, file,
> + DRM_IOCTL_RADEON_INFO, arg);
> +
> + kinfo.value = (uint64_t) uptr;
> +
> + uinfo = compat_alloc_user_space(sizeof(*uinfo));
> + if (copy_to_user(uinfo, &kinfo, sizeof(kinfo)))
> + return -EFAULT;
> +
> + return drm_ioctl(file->f_dentry->d_inode, file,
> + DRM_IOCTL_RADEON_INFO, (unsigned long) uinfo);
> +}
IMHO a better way to handle the radeon specific ioctls would be to
avoid the compat_alloc_user_space and just define the common function
taking a kernel pointer, with two implementations of the copy operation:
static int __radeon_info_ioctl(struct file *file, struct drm_radeon_info *info);
static int radeon_info_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct drm_radeon_info kinfo;
if (copy_from_user(&kinfo, (void __user *)arg, sizeof(kinfo)))
return -EFAULT;
return __radeon_info_ioctl(file, cmd, &kinfo);
}
static int radeon_info_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct compat_drm_radeon_info kinfo;
if (copy_from_user(&kinfo, compat_ptr(arg), sizeof(kinfo)))
return -EFAULT;
kinfo.value = (u64)compat_ptr(kinfo.value);
return __radeon_info_ioctl(file, cmd, &kinfo);
}
> @@ -426,13 +507,20 @@ long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> {
> unsigned int nr = DRM_IOCTL_NR(cmd);
> + drm_ioctl_compat_t *fn = NULL;
> int ret;
>
> if (nr < DRM_COMMAND_BASE)
> return drm_compat_ioctl(filp, cmd, arg);
>
> + if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_kms_ioctls))
> + fn = radeon_compat_kms_ioctls[nr - DRM_COMMAND_BASE];
> +
> lock_kernel(); /* XXX for now */
> - ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
> + if (fn != NULL)
> + ret = (*fn) (filp, cmd, arg);
> + else
> + ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
> unlock_kernel();
This could consequently become
if (nr < DRM_COMMAND_BASE)
return drm_compat_ioctl(filp, cmd, arg);
+ switch (cmd) {
+ case DRM_IOCTL_RADEON_INFO:
+ return radeon_info_compat_ioctl(filp, cmd, arg);
+ case ...
+ }
+
lock_kernel(); /* XXX for now */
ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
unlock_kernel();
The other changes in your patch look good to me.
Arnd <><
next prev parent reply other threads:[~2009-10-28 12:13 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-28 1:22 is avoiding compat ioctls possible? Dave Airlie
2009-10-28 2:25 ` David Miller
2009-10-28 3:01 ` Dave Airlie
2009-10-28 2:53 ` Andi Kleen
2009-10-28 3:05 ` Dave Airlie
2009-10-28 3:19 ` Andi Kleen
2009-10-28 3:28 ` Dave Airlie
2009-10-28 3:34 ` Andi Kleen
2009-10-28 3:43 ` David Miller
2009-10-28 3:41 ` David Miller
2009-10-28 21:05 ` Maciej W. Rozycki
2009-10-29 8:27 ` Arnd Bergmann
2009-10-28 3:38 ` David Miller
2009-10-28 3:43 ` Dave Airlie
2009-10-28 3:45 ` David Miller
2009-10-28 3:51 ` Andi Kleen
2009-10-28 3:54 ` Dave Airlie
2009-10-28 5:28 ` David Miller
2009-10-28 5:42 ` Dave Airlie
2009-10-28 6:04 ` David Miller
2009-10-28 7:53 ` David Miller
2009-10-28 7:59 ` Andi Kleen
2009-10-28 8:11 ` David Miller
2009-10-28 8:19 ` Andi Kleen
2009-10-28 8:28 ` David Miller
2009-10-28 12:13 ` Arnd Bergmann [this message]
2009-10-28 12:16 ` David Miller
2009-10-28 15:40 ` Arnd Bergmann
2009-10-29 5:41 ` David Miller
2009-10-29 8:16 ` Arnd Bergmann
2009-10-29 8:34 ` Heiko Carstens
2009-10-29 8:39 ` David Miller
2009-10-28 12:17 ` David Miller
2009-10-30 1:13 ` Dave Airlie
2009-10-30 10:13 ` Arnd Bergmann
2009-11-18 0:26 ` Dave Airlie
2009-11-18 9:09 ` Andi Kleen
2009-11-18 14:42 ` Arnd Bergmann
2009-10-28 3:37 ` David Miller
2009-10-28 4:36 ` Andi Kleen
2009-10-28 5:29 ` David Miller
2009-10-28 10:27 ` Arnd Bergmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200910281313.32827.arnd@arndb.de \
--to=arndbergmann@googlemail.com \
--cc=airlied@linux.ie \
--cc=andi@firstfloor.org \
--cc=davem@davemloft.net \
--cc=dri-devel@lists.sourceforge.net \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.