[linux-dvb] DVB-S2 API vs. HVR4000: When?

Johannes Stezenbach js at linuxtv.org
Mon Nov 5 18:43:39 CET 2007


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



More information about the linux-dvb mailing list