[PATCH v2 5/6] drm/crtc: add sanity checks to create_dumb()
David Herrmann
dh.herrmann at gmail.com
Wed Feb 5 13:29:18 PST 2014
ping
On Thu, Jan 23, 2014 at 3:10 PM, David Herrmann <dh.herrmann at gmail.com> wrote:
> Hi
>
> On Thu, Jan 23, 2014 at 2:55 PM, Ville Syrjälä
> <ville.syrjala at linux.intel.com> wrote:
>> On Thu, Jan 23, 2014 at 01:53:15PM +0100, David Herrmann wrote:
>>> Lets make sure some basic expressions are always true:
>>> bpp != NULL
>>> width != NULL
>>> height != NULL
>>> stride = bpp * width < 2^32
>>> size = stride * height < 2^32
>>> PAGE_ALIGN(size) < 2^32
>>>
>>> At least the udl driver doesn't check for multiplication-overflows, so
>>> lets just make sure it will never happen. These checks allow drivers to do
>>> any 32bit math without having to test for mult-overflows themselves.
>>>
>>> The two divisions might hurt performance a bit, but dumb_create() is only
>>> used for scanout-buffers, so that should be fine. We could use 64bit math
>>> to avoid the divisions, but that may be slow on 32bit machines.. Or maybe
>>> there should just be a "safe_mult32()" helper, which currently doesn't
>>> exist (I think?).
>>>
>>> Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
>>> Signed-off-by: David Herrmann <dh.herrmann at gmail.com>
>>> ---
>>> drivers/gpu/drm/drm_crtc.c | 17 +++++++++++++++++
>>> 1 file changed, 17 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
>>> index 266a01d..2b50702 100644
>>> --- a/drivers/gpu/drm/drm_crtc.c
>>> +++ b/drivers/gpu/drm/drm_crtc.c
>>> @@ -3738,9 +3738,26 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev,
>>> void *data, struct drm_file *file_priv)
>>> {
>>> struct drm_mode_create_dumb *args = data;
>>> + u32 cpp, stride, size;
>>>
>>> if (!dev->driver->dumb_create)
>>> return -ENOSYS;
>>> + if (!args->width || !args->height || !args->bpp)
>>> + return -EINVAL;
>>> +
>>> + /* overflow checks for 32bit size calculations */
>>> + cpp = DIV_ROUND_UP(args->bpp, 8);
>>> + if (cpp > 0xffffffffU / args->width)
>>> + return -EINVAL;
>>
>> IIRC I used -ERANGE for such things in some drm_framebuffer checks. Not
>> sure if that's the best error value or not, but using the same one in
>> both places would be nice.
>
> I'm actually a fan of EINVAL here, as this is really more about "do
> the arguments make sense?" than "does the range exceed the driver's
> capabilities?" But what do I know.. So more comments on that are
> welcome. And btw., we already mix EINVAL and ERANGE so this would just
> contribute to the already existing mess (see the stride verifications
> which usually return EINVAL, but the overflow checks often return
> ERANGE).
>
> Thanks
> David
>
>>> + stride = cpp * args->width;
>>> + if (args->height > 0xffffffffU / stride)
>>> + return -EINVAL;
>>> +
>>> + /* test for wrap-around */
>>> + size = args->height * stride;
>>> + if (PAGE_ALIGN(size) == 0)
>>> + return -EINVAL;
>>> +
>>> return dev->driver->dumb_create(file_priv, dev, args);
>>> }
>>>
>>> --
>>> 1.8.5.3
>>>
>>> _______________________________________________
>>> dri-devel mailing list
>>> dri-devel at lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>>
>> --
>> Ville Syrjälä
>> Intel OTC
More information about the dri-devel
mailing list