Loading drivers/gpu/drm/drm_drv.c +75 −38 Original line number Diff line number Diff line Loading @@ -285,6 +285,44 @@ static int drm_version(struct drm_device *dev, void *data, return err; } /** * 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) { /* 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; } /** * Called whenever a process performs an ioctl on /dev/drm. * Loading Loading @@ -350,16 +388,16 @@ 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 { goto err_i1; } retcode = drm_ioctl_permit(ioctl->flags, file_priv); if (unlikely(retcode)) goto err_i1; if (cmd & (IOC_IN | IOC_OUT)) { if (asize <= sizeof(stack_kdata)) { kdata = stack_kdata; Loading Loading @@ -396,7 +434,6 @@ long drm_ioctl(struct file *filp, usize) != 0) retcode = -EFAULT; } } err_i1: if (!ioctl) Loading Loading
drivers/gpu/drm/drm_drv.c +75 −38 Original line number Diff line number Diff line Loading @@ -285,6 +285,44 @@ static int drm_version(struct drm_device *dev, void *data, return err; } /** * 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) { /* 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; } /** * Called whenever a process performs an ioctl on /dev/drm. * Loading Loading @@ -350,16 +388,16 @@ 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 { goto err_i1; } retcode = drm_ioctl_permit(ioctl->flags, file_priv); if (unlikely(retcode)) goto err_i1; if (cmd & (IOC_IN | IOC_OUT)) { if (asize <= sizeof(stack_kdata)) { kdata = stack_kdata; Loading Loading @@ -396,7 +434,6 @@ long drm_ioctl(struct file *filp, usize) != 0) retcode = -EFAULT; } } err_i1: if (!ioctl) Loading