[PATCH] DRM: ensure fbdev helper arrays are appropriately dimensioned
Russell King
rmk+kernel at arm.linux.org.uk
Fri Feb 7 13:12:54 PST 2014
If the number of connectors changes, then it is possible for the fbdev
helper to overrun/underrun some arrays which it allocates. It allocates
these arrays based on mode_config.num_connector but then walks lists
using fb_helper->connector_count to limit the array index. This can
lead to writes off the end of the arrays.
Fix this by allocating the arrays using fb_helper->connector_count.
A similar thing exists for some of the CRTC arrays. For these, use
fb_helper->crtc_count.
Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
David,
Would you consider the following patch to clean up the DRM fb helper a
little - we already record the number of CRTCs and connectors in the
fb_helper structure. While we officially don't support hotplugging,
this is more a consistency cleanup, so that we're dimensioning the
arrays using the same sizing that we will then use to walk over them.
Thanks.
drivers/gpu/drm/drm_fb_helper.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 0a19401aff80..0da727e55fd2 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1360,7 +1360,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
if (modes[n] == NULL)
return best_score;
- crtcs = kzalloc(dev->mode_config.num_connector *
+ crtcs = kcalloc(fb_helper->crtc_count,
sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
if (!crtcs)
return best_score;
@@ -1406,7 +1406,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
if (score > best_score) {
best_score = score;
memcpy(best_crtcs, crtcs,
- dev->mode_config.num_connector *
+ fb_helper->crtc_count *
sizeof(struct drm_fb_helper_crtc *));
}
}
@@ -1430,11 +1430,11 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
width = dev->mode_config.max_width;
height = dev->mode_config.max_height;
- crtcs = kcalloc(dev->mode_config.num_connector,
+ crtcs = kcalloc(fb_helper->connector_count,
sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
- modes = kcalloc(dev->mode_config.num_connector,
+ modes = kcalloc(fb_helper->connector_count,
sizeof(struct drm_display_mode *), GFP_KERNEL);
- enabled = kcalloc(dev->mode_config.num_connector,
+ enabled = kcalloc(fb_helper->connector_count,
sizeof(bool), GFP_KERNEL);
if (!crtcs || !modes || !enabled) {
DRM_ERROR("Memory allocation failed\n");
@@ -1447,8 +1447,8 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
if (!(fb_helper->funcs->initial_config &&
fb_helper->funcs->initial_config(fb_helper, crtcs, modes,
enabled, width, height))) {
- memset(modes, 0, dev->mode_config.num_connector*sizeof(modes[0]));
- memset(crtcs, 0, dev->mode_config.num_connector*sizeof(crtcs[0]));
+ memset(modes, 0, fb_helper->connector_count * sizeof(modes[0]));
+ memset(crtcs, 0, fb_helper->connector_count * sizeof(crtcs[0]));
if (!drm_target_cloned(fb_helper,
modes, enabled, width, height) &&
--
1.8.3.1
More information about the dri-devel
mailing list