aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Brezillon <boris.brezillon@free-electrons.com>2016-08-08 20:16:18 -0400
committerDave Airlie <airlied@redhat.com>2016-08-08 23:01:47 -0400
commit36e9d08b58f44c3a02974c405ccaaa6ecfaf05b8 (patch)
tree02e9bc0c84ac36db3b49c8be2620dc949f4195ad
parent210a021dab639694600450c14b877bf3e3240adc (diff)
drm/cirrus: Fix NULL pointer dereference when registering the fbdev
cirrus_modeset_init() is initializing/registering the emulated fbdev and, since commit c61b93fe51b1 ("drm/atomic: Fix remaining places where !funcs->best_encoder is valid"), DRM internals can access/test some of the fields in mode_config->funcs as part of the fbdev registration process. Make sure dev->mode_config.funcs is properly set to avoid dereferencing a NULL pointer. Reported-by: Mike Marshall <hubcap@omnibond.com> Reported-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Fixes: c61b93fe51b1 ("drm/atomic: Fix remaining places where !funcs->best_encoder is valid") Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_main.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
index 80446e2d3ab6..76bcb43e7c06 100644
--- a/drivers/gpu/drm/cirrus/cirrus_main.c
+++ b/drivers/gpu/drm/cirrus/cirrus_main.c
@@ -185,14 +185,23 @@ int cirrus_driver_load(struct drm_device *dev, unsigned long flags)
185 goto out; 185 goto out;
186 } 186 }
187 187
188 /*
189 * cirrus_modeset_init() is initializing/registering the emulated fbdev
190 * and DRM internals can access/test some of the fields in
191 * mode_config->funcs as part of the fbdev registration process.
192 * Make sure dev->mode_config.funcs is properly set to avoid
193 * dereferencing a NULL pointer.
194 * FIXME: mode_config.funcs assignment should probably be done in
195 * cirrus_modeset_init() (that's a common pattern seen in other DRM
196 * drivers).
197 */
198 dev->mode_config.funcs = &cirrus_mode_funcs;
188 r = cirrus_modeset_init(cdev); 199 r = cirrus_modeset_init(cdev);
189 if (r) { 200 if (r) {
190 dev_err(&dev->pdev->dev, "Fatal error during modeset init: %d\n", r); 201 dev_err(&dev->pdev->dev, "Fatal error during modeset init: %d\n", r);
191 goto out; 202 goto out;
192 } 203 }
193 204
194 dev->mode_config.funcs = (void *)&cirrus_mode_funcs;
195
196 return 0; 205 return 0;
197out: 206out:
198 cirrus_driver_unload(dev); 207 cirrus_driver_unload(dev);