dri/kms: Always zero out struct drm_mode_create_dumb
authorThierry Reding <treding@nvidia.com>
Thu, 13 Nov 2014 18:05:51 +0000 (19:05 +0100)
committerEmil Velikov <emil.l.velikov@gmail.com>
Sun, 16 Nov 2014 01:03:40 +0000 (01:03 +0000)
The DRM_IOCTL_MODE_CREATE_DUMB (and others) IOCTL isn't very rigorously
specified, which has the effect that some kernel drivers do not consider
the .pitch and .size fields of struct drm_mode_create_dumb outputs only.
Instead they will use these as lower bounds and overwrite them only if
the values that they compute are larger than what userspace provided.

This works if and only if userspace initializes the fields explicitly to
either 0 or some meaningful value. However, if userspace just leaves the
values uninitialized and the struct drm_mode_create_dumb is allocated on
the stack for example, the driver may try to overallocate buffers.

Fortunately most userspace does zero out the structure before passing it
to the IOCTL, but there are rare exceptions. Mesa is one of them. In an
attempt to rectify this situation, kernel drivers are being updated to
not use the .pitch and .size fields as inputs. However in order to fix
the issue with older kernels, make sure that Mesa always zeros out the
structure as well.

Future IOCTLs should be more rigorously defined so that structures can
be validated and IOCTLs rejected if output fields aren't set to zero.

Signed-off-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c
src/gbm/backends/dri/gbm_dri.c

index 49b2e6596ac9cbed98d1890b8f26d7b81b6eefae..ed34dfa6cbc6c15acb6e772d0c62f10c58c819fa 100644 (file)
@@ -131,10 +131,10 @@ kms_sw_displaytarget_create(struct sw_winsys *ws,
    kms_sw_dt->width = width;
    kms_sw_dt->height = height;
 
+   memset(&create_req, 0, sizeof(create_req));
    create_req.bpp = 32;
    create_req.width = width;
    create_req.height = height;
-   create_req.handle = 0;
    ret = drmIoctl(kms_sw->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_req);
    if (ret)
       goto free_bo;
index 066426617bac561898eb35af47e37680b78a81c7..39e6b30d473aa298030e929f6de09b4ef0fbcf40 100644 (file)
@@ -774,6 +774,7 @@ create_dumb(struct gbm_device *gbm,
    if (bo == NULL)
       return NULL;
 
+   memset(&create_arg, 0, sizeof(create_arg));
    create_arg.bpp = 32;
    create_arg.width = width;
    create_arg.height = height;