[PATCH 2/5] drm: Break out ioctl permission check to a separate function
David Herrmann
dh.herrmann at gmail.com
Thu Mar 13 04:19:42 PDT 2014
Hi
On Thu, Mar 13, 2014 at 11:57 AM, Thomas Hellstrom
<thellstrom at vmware.com> wrote:
> Helps reviewing and understanding these checks.
>
> Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
> ---
> drivers/gpu/drm/drm_drv.c | 116 ++++++++++++++++++++++++++++++---------------
> 1 file changed, 78 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 345be03..0afc6e4 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -285,6 +285,47 @@ static int drm_version(struct drm_device *dev, void *data,
> return err;
> }
>
> +
Why the double blank line?
> +/**
> + * drm_ioctl_permit - Check ioctl permissions against caller
> + *
> + * @flags: ioctl permission flags.
> + * @file_priv: Pointer to struct drm_file identifying the caller.
> + *
> + * Checks whether the caller is allowed to run an ioctl with the
> + * indicated permissions. If so, returns zero. Otherwise returns an
> + * error code suitable for ioctl return.
> + */
> +static int drm_ioctl_permit(u32 flags, struct drm_file *file_priv)
> +{
> +
We don't do blank lines after function-headers.
> + /* ROOT_ONLY is only for CAP_SYS_ADMIN */
> + if (unlikely((flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)))
> + return -EACCES;
> +
> + /* AUTH is only for authenticated or render client */
> + if (unlikely((flags & DRM_AUTH) && !drm_is_render_client(file_priv) &&
> + !file_priv->authenticated))
> + return -EACCES;
> +
> + /* MASTER is only for master */
> + if (unlikely((flags & DRM_MASTER) && !file_priv->is_master))
> + return -EACCES;
> +
> + /* Control clients must be explicitly allowed */
> + if (unlikely(!(flags & DRM_CONTROL_ALLOW) &&
> + file_priv->minor->type == DRM_MINOR_CONTROL))
> + return -EACCES;
> +
> + /* Render clients must be explicitly allowed */
> + if (unlikely(!(flags & DRM_RENDER_ALLOW) &&
> + drm_is_render_client(file_priv)))
> + return -EACCES;
> +
> + return 0;
> +}
> +
> +
Again, double blank-line.
> /**
> * Called whenever a process performs an ioctl on /dev/drm.
> *
> @@ -350,52 +391,51 @@ long drm_ioctl(struct file *filp,
> /* Do not trust userspace, use our own definition */
> func = ioctl->func;
>
> - if (!func) {
> + if (unlikely(!func)) {
> DRM_DEBUG("no function\n");
> retcode = -EINVAL;
> - } else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) ||
> - ((ioctl->flags & DRM_AUTH) && !drm_is_render_client(file_priv) && !file_priv->authenticated) ||
> - ((ioctl->flags & DRM_MASTER) && !file_priv->is_master) ||
> - (!(ioctl->flags & DRM_CONTROL_ALLOW) && (file_priv->minor->type == DRM_MINOR_CONTROL)) ||
> - (!(ioctl->flags & DRM_RENDER_ALLOW) && drm_is_render_client(file_priv))) {
> - retcode = -EACCES;
> - } else {
> - if (cmd & (IOC_IN | IOC_OUT)) {
> - if (asize <= sizeof(stack_kdata)) {
> - kdata = stack_kdata;
> - } else {
> - kdata = kmalloc(asize, GFP_KERNEL);
> - if (!kdata) {
> - retcode = -ENOMEM;
> - goto err_i1;
> - }
> - }
> - if (asize > usize)
> - memset(kdata + usize, 0, asize - usize);
> - }
> + goto err_i1;
> + }
>
> - if (cmd & IOC_IN) {
> - if (copy_from_user(kdata, (void __user *)arg,
> - usize) != 0) {
> - retcode = -EFAULT;
> + retcode = drm_ioctl_permit(ioctl->flags, file_priv);
> + if (unlikely(retcode))
That "unlikely" seems redundant given that all error paths in
drm_ioctl_permit() already are "unlikely".
Otherwise, patch looks good:
Reviewed-by: David Herrmann <dh.herrmann at gmail.com>
Thanks
David
> + goto err_i1;
> +
> + if (cmd & (IOC_IN | IOC_OUT)) {
> + if (asize <= sizeof(stack_kdata)) {
> + kdata = stack_kdata;
> + } else {
> + kdata = kmalloc(asize, GFP_KERNEL);
> + if (!kdata) {
> + retcode = -ENOMEM;
> goto err_i1;
> }
> - } else
> - memset(kdata, 0, usize);
> -
> - if (ioctl->flags & DRM_UNLOCKED)
> - retcode = func(dev, kdata, file_priv);
> - else {
> - mutex_lock(&drm_global_mutex);
> - retcode = func(dev, kdata, file_priv);
> - mutex_unlock(&drm_global_mutex);
> }
> + if (asize > usize)
> + memset(kdata + usize, 0, asize - usize);
> + }
>
> - if (cmd & IOC_OUT) {
> - if (copy_to_user((void __user *)arg, kdata,
> - usize) != 0)
> - retcode = -EFAULT;
> + if (cmd & IOC_IN) {
> + if (copy_from_user(kdata, (void __user *)arg,
> + usize) != 0) {
> + retcode = -EFAULT;
> + goto err_i1;
> }
> + } else
> + memset(kdata, 0, usize);
> +
> + if (ioctl->flags & DRM_UNLOCKED)
> + retcode = func(dev, kdata, file_priv);
> + else {
> + mutex_lock(&drm_global_mutex);
> + retcode = func(dev, kdata, file_priv);
> + mutex_unlock(&drm_global_mutex);
> + }
> +
> + if (cmd & IOC_OUT) {
> + if (copy_to_user((void __user *)arg, kdata,
> + usize) != 0)
> + retcode = -EFAULT;
> }
>
> err_i1:
> --
> 1.7.10.4
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
More information about the dri-devel
mailing list