Message ID | 1382434683-32048-1-git-send-email-chris@chris-wilson.co.uk (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, Oct 22, 2013 at 10:38:03AM +0100, Chris Wilson wrote: > Prevent the user from passing in an ioctl command with up to 16,383 > bytes specified for the struct to be allocated and copied, and > instead only allocate enough space to satisfy the kernel. > > Suggested-by: Pavel Roskin <proski@gnu.org> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> > Cc: Pavel Roskin <proski@gnu.org> > Cc: dri-devel@lists.freedesktop.org Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > --- > drivers/gpu/drm/drm_drv.c | 30 +++++++++++++----------------- > 1 file changed, 13 insertions(+), 17 deletions(-) > > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c > index 05ad9ba0a67e..8c5fbc9d41ad 100644 > --- a/drivers/gpu/drm/drm_drv.c > +++ b/drivers/gpu/drm/drm_drv.c > @@ -354,6 +354,16 @@ static int drm_version(struct drm_device *dev, void *data, > return err; > } > > +static unsigned ioctl_size(unsigned kcmd, unsigned ucmd, unsigned *ksize, unsigned *usize) > +{ > + *ksize = _IOC_SIZE(kcmd); > + *usize = _IOC_SIZE(ucmd); > + if (*usize > *ksize) > + *usize = *ksize; > + > + return kcmd; > +} > + > /** > * Called whenever a process performs an ioctl on /dev/drm. > * > @@ -393,25 +403,11 @@ long drm_ioctl(struct file *filp, > goto err_i1; > if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && > (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) { > - u32 drv_size; > ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; > - drv_size = _IOC_SIZE(ioctl->cmd_drv); > - usize = asize = _IOC_SIZE(cmd); > - if (drv_size > asize) > - asize = drv_size; > - cmd = ioctl->cmd_drv; > - } > - else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { > - u32 drv_size; > - > + cmd = ioctl_size(ioctl->cmd_drv, cmd, &asize, &usize); > + } else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { > ioctl = &drm_ioctls[nr]; > - > - drv_size = _IOC_SIZE(ioctl->cmd); > - usize = asize = _IOC_SIZE(cmd); > - if (drv_size > asize) > - asize = drv_size; > - > - cmd = ioctl->cmd; > + cmd = ioctl_size(ioctl->cmd, cmd, &asize, &usize); > } else > goto err_i1; > > -- > 1.8.4.rc3 > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel
On Tue, 22 Oct 2013 10:38:03 +0100 Chris Wilson <chris@chris-wilson.co.uk> wrote: > Prevent the user from passing in an ioctl command with up to 16,383 > bytes specified for the struct to be allocated and copied, and > instead only allocate enough space to satisfy the kernel. > > Suggested-by: Pavel Roskin <proski@gnu.org> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> > Cc: Pavel Roskin <proski@gnu.org> > Cc: dri-devel@lists.freedesktop.org Thank you for taking care of that! Reviewed-by: Pavel Roskin <proski@gnu.org>
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 05ad9ba0a67e..8c5fbc9d41ad 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -354,6 +354,16 @@ static int drm_version(struct drm_device *dev, void *data, return err; } +static unsigned ioctl_size(unsigned kcmd, unsigned ucmd, unsigned *ksize, unsigned *usize) +{ + *ksize = _IOC_SIZE(kcmd); + *usize = _IOC_SIZE(ucmd); + if (*usize > *ksize) + *usize = *ksize; + + return kcmd; +} + /** * Called whenever a process performs an ioctl on /dev/drm. * @@ -393,25 +403,11 @@ long drm_ioctl(struct file *filp, goto err_i1; if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) { - u32 drv_size; ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; - drv_size = _IOC_SIZE(ioctl->cmd_drv); - usize = asize = _IOC_SIZE(cmd); - if (drv_size > asize) - asize = drv_size; - cmd = ioctl->cmd_drv; - } - else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { - u32 drv_size; - + cmd = ioctl_size(ioctl->cmd_drv, cmd, &asize, &usize); + } else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { ioctl = &drm_ioctls[nr]; - - drv_size = _IOC_SIZE(ioctl->cmd); - usize = asize = _IOC_SIZE(cmd); - if (drv_size > asize) - asize = drv_size; - - cmd = ioctl->cmd; + cmd = ioctl_size(ioctl->cmd, cmd, &asize, &usize); } else goto err_i1;
Prevent the user from passing in an ioctl command with up to 16,383 bytes specified for the struct to be allocated and copied, and instead only allocate enough space to satisfy the kernel. Suggested-by: Pavel Roskin <proski@gnu.org> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Pavel Roskin <proski@gnu.org> Cc: dri-devel@lists.freedesktop.org --- drivers/gpu/drm/drm_drv.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-)