* [PATCH] hiddev: Add 32bit ioctl compatibilty
@ 2007-10-12 23:51 Philip Langdale
2007-10-13 0:02 ` Al Viro
0 siblings, 1 reply; 7+ messages in thread
From: Philip Langdale @ 2007-10-12 23:51 UTC (permalink / raw)
To: Jiri Kosina; +Cc: LKML
The hiddev driver currently lacks 32bit ioctl compatibility, so
if you're running with a 64bit kernel and 32bit userspace, it won't
work.
I'm pretty sure that the only thing missing is a compat_ioctl
implementation as all structs have fixed size fields.
With this change I can use revoco to configure my MX Revolution mouse.
Signed-off-by: Philip Langdale <philipl@overt.org>
--- linux-2.6.23/drivers/hid/usbhid/hiddev.c 2007-10-09 13:31:38.000000000 -0700
+++ linux-phil/drivers/hid/usbhid/hiddev.c 2007-10-12 15:02:15.000000000 -0700
@@ -34,6 +34,7 @@
#include <linux/usb.h>
#include <linux/hid.h>
#include <linux/hiddev.h>
+#include <linux/compat.h>
#include "usbhid.h"
#ifdef CONFIG_USB_DYNAMIC_MINORS
@@ -738,6 +738,14 @@
return -EINVAL;
}
+#ifdef CONFIG_COMPAT
+static long hiddev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct inode *inode = file->f_path.dentry->d_inode;
+ return hiddev_ioctl(inode, file, cmd, compat_ptr(arg));
+}
+#endif
+
static const struct file_operations hiddev_fops = {
.owner = THIS_MODULE,
.read = hiddev_read,
@@ -747,6 +754,9 @@
.release = hiddev_release,
.ioctl = hiddev_ioctl,
.fasync = hiddev_fasync,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = hiddev_compat_ioctl,
+#endif
};
static struct usb_class_driver hiddev_class = {
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] hiddev: Add 32bit ioctl compatibilty 2007-10-12 23:51 [PATCH] hiddev: Add 32bit ioctl compatibilty Philip Langdale @ 2007-10-13 0:02 ` Al Viro 2007-10-13 17:42 ` Philip Langdale 2007-10-20 15:50 ` [PATCH] compat_ioctl: introduce generic_compat_ioctl helper Arnd Bergmann 0 siblings, 2 replies; 7+ messages in thread From: Al Viro @ 2007-10-13 0:02 UTC (permalink / raw) To: Philip Langdale; +Cc: Jiri Kosina, LKML On Fri, Oct 12, 2007 at 04:51:00PM -0700, Philip Langdale wrote: > The hiddev driver currently lacks 32bit ioctl compatibility, so > if you're running with a 64bit kernel and 32bit userspace, it won't > work. > > I'm pretty sure that the only thing missing is a compat_ioctl > implementation as all structs have fixed size fields. > > +static long hiddev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) > +{ > + struct inode *inode = file->f_path.dentry->d_inode; > + return hiddev_ioctl(inode, file, cmd, compat_ptr(arg)); > +} Just how many instances of that sucker do we need? It's nothing but struct inode *inode = file->f_path.dentry->d_inode; return file->f_op->ioctl(inode, file, cmd, compat_ptr(arg)); ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] hiddev: Add 32bit ioctl compatibilty 2007-10-13 0:02 ` Al Viro @ 2007-10-13 17:42 ` Philip Langdale 2007-10-20 15:50 ` [PATCH] compat_ioctl: introduce generic_compat_ioctl helper Arnd Bergmann 1 sibling, 0 replies; 7+ messages in thread From: Philip Langdale @ 2007-10-13 17:42 UTC (permalink / raw) To: Al Viro; +Cc: Jiri Kosina, LKML Al Viro wrote: >> >> +static long hiddev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) >> +{ >> + struct inode *inode = file->f_path.dentry->d_inode; >> + return hiddev_ioctl(inode, file, cmd, compat_ptr(arg)); >> +} > > Just how many instances of that sucker do we need? It's nothing but > > struct inode *inode = file->f_path.dentry->d_inode; > return file->f_op->ioctl(inode, file, cmd, compat_ptr(arg)); > So, I don't actually know what you're looking for, but of the 140 occasions that .compat_ioctl is implemented in Linus' tree, I can't find another one that actually uses this form. So, writing a shared implementation doesn't pick off any low hanging fruit. Now, it's possible that some of the other implementations could be reduced to this form - but for now, it seems the answer to your question is 'one' in either case. :-) --phil ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] compat_ioctl: introduce generic_compat_ioctl helper 2007-10-13 0:02 ` Al Viro 2007-10-13 17:42 ` Philip Langdale @ 2007-10-20 15:50 ` Arnd Bergmann 2007-10-20 16:03 ` [PATCH] hiddev: simplify 32bit ioctl compatibilty Arnd Bergmann 2007-10-20 16:11 ` [PATCH] compat_ioctl: introduce generic_compat_ioctl helper Christoph Hellwig 1 sibling, 2 replies; 7+ messages in thread From: Arnd Bergmann @ 2007-10-20 15:50 UTC (permalink / raw) To: Al Viro; +Cc: Philip Langdale, Jiri Kosina, LKML Many drivers use only compatible ioctl numbers. In order to avoid having to write a special compat_ioctl handler for each of them or listing every ioctl number in fs/compat_ioctl.c, let's introduce a generic handler that simply calls the driver specific f_op->unlocked_ioctl() or f_op->ioctl() handler. Signed-off-by: Arnd Bergman <arnd@arndb.de> --- On Saturday 13 October 2007, Al Viro wrote: > Just how many instances of that sucker do we need? It's nothing but > > struct inode *inode = file->f_path.dentry->d_inode; > return file->f_op->ioctl(inode, file, cmd, compat_ptr(arg)); Is this what you had in mind? I've been meaning to do something like it for some time, but had forgotten about it. I guess we can kill a significant amount of COMPATIBLE_IOCTL lines in fs/compat_ioctl.c with this. Index: linux-2.6/fs/compat_ioctl.c =================================================================== --- linux-2.6.orig/fs/compat_ioctl.c +++ linux-2.6/fs/compat_ioctl.c @@ -1877,6 +1877,30 @@ lp_timeout_trans(unsigned int fd, unsign return sys_ioctl(fd, cmd, (unsigned long)tn); } +/* + * Helper function for device drivers that only have COMPATIBLE_IOCTL + * numbers. This can be used as f_op->compat_ioctl without any #ifdef + * and will simply call the native ioctl handler with the argument + * pointer. + * Don't use for drivers that interpret arg as an unsigned long instead + * of a pointer. + */ +long generic_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret = -ENOTTY; + arg = (unsigned long)compat_ptr(arg); + + if (file->f_op->unlocked_ioctl) + ret = file->f_op->unlocked_ioctl(file, cmd, arg); + else if (file->f_op->ioctl) { + lock_kernel(); + ret = file->f_op->ioctl(file->f_dentry->d_inode, file, cmd, arg); + unlock_kernel(); + } + + return ret; +} +EXPORT_SYMBOL_GPL(generic_compat_ioctl); typedef int (*ioctl_trans_handler_t)(unsigned int, unsigned int, unsigned long, struct file *); Index: linux-2.6/include/linux/fs.h =================================================================== --- linux-2.6.orig/include/linux/fs.h +++ linux-2.6/include/linux/fs.h @@ -1807,6 +1807,12 @@ extern void do_generic_mapping_read(stru extern int generic_segment_checks(const struct iovec *iov, unsigned long *nr_segs, size_t *count, int access_flags); +#ifdef CONFIG_COMPAT +extern long generic_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +#else +#define generic_compat_ioctl (long (*)(struct file *, unsigned int, unsigned long))NULL +#endif + /* fs/splice.c */ extern ssize_t generic_file_splice_read(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] hiddev: simplify 32bit ioctl compatibilty 2007-10-20 15:50 ` [PATCH] compat_ioctl: introduce generic_compat_ioctl helper Arnd Bergmann @ 2007-10-20 16:03 ` Arnd Bergmann 2007-10-20 16:11 ` [PATCH] compat_ioctl: introduce generic_compat_ioctl helper Christoph Hellwig 1 sibling, 0 replies; 7+ messages in thread From: Arnd Bergmann @ 2007-10-20 16:03 UTC (permalink / raw) To: Al Viro; +Cc: Philip Langdale, Jiri Kosina, LKML hiddev has both entries in fs/compat_ioctl.c and its own compat_ioctl() handler. Remove both and use the new generic_compat_ioctl helper instead. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Index: linux-2.6/drivers/hid/hidraw.c =================================================================== --- linux-2.6.orig/drivers/hid/hidraw.c +++ linux-2.6/drivers/hid/hidraw.c @@ -268,6 +268,7 @@ static const struct file_operations hidr .open = hidraw_open, .release = hidraw_release, .ioctl = hidraw_ioctl, + .compat_ioctl = generic_compat_ioctl, }; void hidraw_report_event(struct hid_device *hid, u8 *data, int len) Index: linux-2.6/drivers/hid/usbhid/hiddev.c =================================================================== --- linux-2.6.orig/drivers/hid/usbhid/hiddev.c +++ linux-2.6/drivers/hid/usbhid/hiddev.c @@ -739,14 +739,6 @@ inval: return -EINVAL; } -#ifdef CONFIG_COMPAT -static long hiddev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct inode *inode = file->f_path.dentry->d_inode; - return hiddev_ioctl(inode, file, cmd, compat_ptr(arg)); -} -#endif - static const struct file_operations hiddev_fops = { .owner = THIS_MODULE, .read = hiddev_read, @@ -756,9 +748,7 @@ static const struct file_operations hidd .release = hiddev_release, .ioctl = hiddev_ioctl, .fasync = hiddev_fasync, -#ifdef CONFIG_COMPAT - .compat_ioctl = hiddev_compat_ioctl, -#endif + .compat_ioctl = generic_compat_ioctl, }; static struct usb_class_driver hiddev_class = { Index: linux-2.6/fs/compat_ioctl.c =================================================================== --- linux-2.6.orig/fs/compat_ioctl.c +++ linux-2.6/fs/compat_ioctl.c @@ -102,8 +102,6 @@ #include <linux/filter.h> #include <linux/pktcdvd.h> -#include <linux/hiddev.h> - #include <linux/dvb/audio.h> #include <linux/dvb/dmx.h> #include <linux/dvb/frontend.h> @@ -2575,23 +2573,6 @@ COMPATIBLE_IOCTL(SIOCSIWPOWER) COMPATIBLE_IOCTL(SIOCGIWPOWER) COMPATIBLE_IOCTL(SIOCSIWAUTH) COMPATIBLE_IOCTL(SIOCGIWAUTH) -/* hiddev */ -COMPATIBLE_IOCTL(HIDIOCGVERSION) -COMPATIBLE_IOCTL(HIDIOCAPPLICATION) -COMPATIBLE_IOCTL(HIDIOCGDEVINFO) -COMPATIBLE_IOCTL(HIDIOCGSTRING) -COMPATIBLE_IOCTL(HIDIOCINITREPORT) -COMPATIBLE_IOCTL(HIDIOCGREPORT) -COMPATIBLE_IOCTL(HIDIOCSREPORT) -COMPATIBLE_IOCTL(HIDIOCGREPORTINFO) -COMPATIBLE_IOCTL(HIDIOCGFIELDINFO) -COMPATIBLE_IOCTL(HIDIOCGUSAGE) -COMPATIBLE_IOCTL(HIDIOCSUSAGE) -COMPATIBLE_IOCTL(HIDIOCGUCODE) -COMPATIBLE_IOCTL(HIDIOCGFLAG) -COMPATIBLE_IOCTL(HIDIOCSFLAG) -COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINDEX) -COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINFO) /* dvb */ COMPATIBLE_IOCTL(AUDIO_STOP) COMPATIBLE_IOCTL(AUDIO_PLAY) ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] compat_ioctl: introduce generic_compat_ioctl helper 2007-10-20 15:50 ` [PATCH] compat_ioctl: introduce generic_compat_ioctl helper Arnd Bergmann 2007-10-20 16:03 ` [PATCH] hiddev: simplify 32bit ioctl compatibilty Arnd Bergmann @ 2007-10-20 16:11 ` Christoph Hellwig 2007-10-20 16:23 ` Arnd Bergmann 1 sibling, 1 reply; 7+ messages in thread From: Christoph Hellwig @ 2007-10-20 16:11 UTC (permalink / raw) To: Arnd Bergmann; +Cc: Al Viro, Philip Langdale, Jiri Kosina, LKML On Sat, Oct 20, 2007 at 05:50:57PM +0200, Arnd Bergmann wrote: > Many drivers use only compatible ioctl numbers. In order to > avoid having to write a special compat_ioctl handler for each > of them or listing every ioctl number in fs/compat_ioctl.c, > let's introduce a generic handler that simply calls the > driver specific f_op->unlocked_ioctl() or f_op->ioctl() handler. At least for the unlocked_ioctl case this is not nessecary because the driver an simply set both the unlocked_ioctl and compat_ioctl handlers to the same function. For the drivers not using unlocked_ioctl yet a function like this makes sense in theory, but I'd prefer to just switch them to ->unlocked_ioctl. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] compat_ioctl: introduce generic_compat_ioctl helper 2007-10-20 16:11 ` [PATCH] compat_ioctl: introduce generic_compat_ioctl helper Christoph Hellwig @ 2007-10-20 16:23 ` Arnd Bergmann 0 siblings, 0 replies; 7+ messages in thread From: Arnd Bergmann @ 2007-10-20 16:23 UTC (permalink / raw) To: Christoph Hellwig; +Cc: Al Viro, Philip Langdale, Jiri Kosina, LKML On Saturday 20 October 2007, Christoph Hellwig wrote: > At least for the unlocked_ioctl case this is not nessecary because > the driver an simply set both the unlocked_ioctl and compat_ioctl > handlers to the same function. For the drivers not using unlocked_ioctl > yet a function like this makes sense in theory, but I'd prefer to > just switch them to ->unlocked_ioctl. > There is still the problem with s390 compat_ptr() conversion, a driver using the same handler for both may interpret a pointer with the high bit set as out of range. Arnd <>< ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2007-10-20 16:23 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-10-12 23:51 [PATCH] hiddev: Add 32bit ioctl compatibilty Philip Langdale 2007-10-13 0:02 ` Al Viro 2007-10-13 17:42 ` Philip Langdale 2007-10-20 15:50 ` [PATCH] compat_ioctl: introduce generic_compat_ioctl helper Arnd Bergmann 2007-10-20 16:03 ` [PATCH] hiddev: simplify 32bit ioctl compatibilty Arnd Bergmann 2007-10-20 16:11 ` [PATCH] compat_ioctl: introduce generic_compat_ioctl helper Christoph Hellwig 2007-10-20 16:23 ` Arnd Bergmann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox