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
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb