Re: [PATCH v4 5/5] media: Support variable size IOCTL arguments

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 08/22/2016 02:55 PM, Hans Verkuil wrote:
> On 08/11/2016 10:29 PM, Sakari Ailus wrote:
>> Maintain a list of supported IOCTL argument sizes and allow only those in
>> the list.
>>
>> As an additional bonus, IOCTL handlers will be able to check whether the
>> caller actually set (using the argument size) the field vs. assigning it
>> to zero. Separate macro can be provided for that.
>>
>> This will be easier for applications as well since there is no longer the
>> problem of setting the reserved fields zero, or at least it is a lesser
>> problem.
>>
>> Signed-off-by: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx>
> 
> Acked-by: Hans Verkuil <hans.verkuil@xxxxxxxxx>

As discussed in v3, I will probably park this patch for now since we don't need
this functionality today.

Regards,

	Hans

> 
>> ---
>>  drivers/media/media-device.c | 56 ++++++++++++++++++++++++++++++++++++++++----
>>  1 file changed, 51 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
>> index 6f565a2..aa37520 100644
>> --- a/drivers/media/media-device.c
>> +++ b/drivers/media/media-device.c
>> @@ -384,22 +384,36 @@ static long copy_arg_to_user(void __user *uarg, void *karg, unsigned int cmd)
>>  /* Do acquire the graph mutex */
>>  #define MEDIA_IOC_FL_GRAPH_MUTEX	BIT(0)
>>  
>> -#define MEDIA_IOC_ARG(__cmd, func, fl, from_user, to_user)		\
>> +#define MEDIA_IOC_SZ_ARG(__cmd, func, fl, alt_sz, from_user, to_user)	\
>>  	[_IOC_NR(MEDIA_IOC_##__cmd)] = {				\
>>  		.cmd = MEDIA_IOC_##__cmd,				\
>>  		.fn = (long (*)(struct media_device *, void *))func,	\
>>  		.flags = fl,						\
>> +		.alt_arg_sizes = alt_sz,				\
>>  		.arg_from_user = from_user,				\
>>  		.arg_to_user = to_user,					\
>>  	}
>>  
>> -#define MEDIA_IOC(__cmd, func, fl)					\
>> -	MEDIA_IOC_ARG(__cmd, func, fl, copy_arg_from_user, copy_arg_to_user)
>> +#define MEDIA_IOC_ARG(__cmd, func, fl, from_user, to_user)		\
>> +	MEDIA_IOC_SZ_ARG(__cmd, func, fl, NULL, from_user, to_user)
>> +
>> +#define MEDIA_IOC_SZ(__cmd, func, fl, alt_sz)			\
>> +	MEDIA_IOC_SZ_ARG(__cmd, func, fl, alt_sz,		\
>> +			 copy_arg_from_user, copy_arg_to_user)
>> +
>> +#define MEDIA_IOC(__cmd, func, fl)				\
>> +	MEDIA_IOC_ARG(__cmd, func, fl,				\
>> +		      copy_arg_from_user, copy_arg_to_user)
>>  
>>  /* the table is indexed by _IOC_NR(cmd) */
>>  struct media_ioctl_info {
>>  	unsigned int cmd;
>>  	unsigned short flags;
>> +	/*
>> +	 * Sizes of the alternative arguments. If there are none, this
>> +	 * pointer is NULL.
>> +	 */
>> +	const unsigned short *alt_arg_sizes;
>>  	long (*fn)(struct media_device *dev, void *arg);
>>  	long (*arg_from_user)(void *karg, void __user *uarg, unsigned int cmd);
>>  	long (*arg_to_user)(void __user *uarg, void *karg, unsigned int cmd);
>> @@ -413,11 +427,40 @@ static const struct media_ioctl_info ioctl_info[] = {
>>  	MEDIA_IOC(G_TOPOLOGY, media_device_get_topology, MEDIA_IOC_FL_GRAPH_MUTEX),
>>  };
>>  
>> +#define MASK_IOC_SIZE(cmd) \
>> +	((cmd) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
>> +
>>  static inline long is_valid_ioctl(const struct media_ioctl_info *info,
>>  				  unsigned int cmd)
>>  {
>> -	return (_IOC_NR(cmd) >= ARRAY_SIZE(ioctl_info)
>> -		|| info[_IOC_NR(cmd)].cmd != cmd) ? -ENOIOCTLCMD : 0;
>> +	const unsigned short *alt_arg_sizes;
>> +
>> +	if (_IOC_NR(cmd) >= ARRAY_SIZE(ioctl_info))
>> +		return -ENOIOCTLCMD;
>> +
>> +	info += _IOC_NR(cmd);
>> +
>> +	if (info->cmd == cmd)
>> +		return 0;
>> +
>> +	/*
>> +	 * Verify that the size-dependent patch of the IOCTL command
>> +	 * matches and that the size does not exceed the principal
>> +	 * argument size.
>> +	 */
>> +	if (MASK_IOC_SIZE(info->cmd) != MASK_IOC_SIZE(cmd)
>> +	    || _IOC_SIZE(info->cmd) < _IOC_SIZE(cmd))
>> +		return -ENOIOCTLCMD;
>> +
>> +	alt_arg_sizes = info->alt_arg_sizes;
>> +	if (!alt_arg_sizes)
>> +		return -ENOIOCTLCMD;
>> +
>> +	for (; *alt_arg_sizes; alt_arg_sizes++)
>> +		if (_IOC_SIZE(cmd) == *alt_arg_sizes)
>> +			return 0;
>> +
>> +	return -ENOIOCTLCMD;
>>  }
>>  
>>  static long __media_device_ioctl(
>> @@ -448,6 +491,9 @@ static long __media_device_ioctl(
>>  			goto out_free;
>>  	}
>>  
>> +	/* Set the rest of the argument struct to zero */
>> +	memset(karg + _IOC_SIZE(cmd), 0, _IOC_SIZE(info->cmd) - _IOC_SIZE(cmd));
>> +
>>  	if (info->flags & MEDIA_IOC_FL_GRAPH_MUTEX)
>>  		mutex_lock(&dev->graph_mutex);
>>  
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux