On Mon, Nov 05, 2007, Johannes Stezenbach wrote: > > Of course you can have variable length args to ioctl(). It's > just that you can't let dvb_usercopy() do the work anymore but > have to call copy_from_user() yourself, but I would favor a simple, > generic API anytime over one with unnecessary, arbitrary > limits, so IMHO it's worth the little extra effort. > > #define DVB_TUNE _IOC(_IOC_WRITE,'o',82,0) > > plus Here's a better patch, still untested but without obvious bugs, I hope ;-) : diff -r 1acfe4149714 linux/drivers/media/dvb/dvb-core/dvbdev.c --- a/linux/drivers/media/dvb/dvb-core/dvbdev.c Mon Nov 05 10:30:39 2007 -0200 +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c Mon Nov 05 18:41:43 2007 +0100 @@ -362,9 +362,11 @@ int dvb_usercopy(struct inode *inode, st case _IOC_READ: /* some v4l ioctls are marked wrong ... */ case _IOC_WRITE: case (_IOC_WRITE | _IOC_READ): - if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { + if (_IOC_SIZE(cmd) == 0) + parg = arg; + else if (_IOC_SIZE(cmd) <= sizeof(sbuf)) parg = sbuf; - } else { + else { /* too big to allocate from stack */ mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); if (NULL == mbuf) @@ -373,7 +375,7 @@ int dvb_usercopy(struct inode *inode, st } err = -EFAULT; - if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) + if (_IOC_SIZE(cmd) && copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) goto out; break; } @@ -390,7 +392,7 @@ int dvb_usercopy(struct inode *inode, st { case _IOC_READ: case (_IOC_WRITE | _IOC_READ): - if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) + if (_IOC_SIZE(cmd) && copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) err = -EFAULT; break; } Johannes _______________________________________________ linux-dvb mailing list linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb