drm: add a check for x/y in drm_mode_setcrtc
authorZhao Junwang <zhjwpku@gmail.com>
Tue, 7 Jul 2015 09:08:35 +0000 (17:08 +0800)
committerDanny Wood <danwood76@gmail.com>
Tue, 29 Jan 2019 13:09:21 +0000 (13:09 +0000)
commit 01447e9f04ba1c49a9534ae6a5a6f26c2bb05226 upstream.

legacy setcrtc ioctl does take a 32 bit value which might indeed
overflow

the checks of crtc_req->x > INT_MAX and crtc_req->y > INT_MAX aren't
needed any more with this

v2: -polish the annotation according to Daniel's comment

Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Zhao Junwang <zhjwpku@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/drm_crtc.c

index 8759d699bd8e1f8aafa88bf0e5682d1c2cf8a1fd..c24c356068368ebd5dc6d2aec2c01bece9c3e64a 100644 (file)
@@ -1955,8 +1955,11 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
        if (!drm_core_check_feature(dev, DRIVER_MODESET))
                return -EINVAL;
 
-       /* For some reason crtc x/y offsets are signed internally. */
-       if (crtc_req->x > INT_MAX || crtc_req->y > INT_MAX)
+       /*
+        * Universal plane src offsets are only 16.16, prevent havoc for
+        * drivers using universal plane code internally.
+        */
+       if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
                return -ERANGE;
 
        drm_modeset_lock_all(dev);