[PATCH] DRM: ensure fbdev helper arrays are appropriately dimensioned (original) (raw)

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_connectorsizeof(modes[0])); - memset(crtcs, 0, dev->mode_config.num_connectorsizeof(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