From: Seung-Woo Kim Date: Fri, 15 Jan 2021 04:41:36 +0000 (+0900) Subject: amlogic: drm/meson: Fix plane state out-of-bounds access X-Git-Tag: submit/tizen/20210204.012538~23 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=019788d0573129ecfc7ecaa0de6a09e348b3e24d;p=platform%2Fkernel%2Flinux-amlogic.git amlogic: drm/meson: Fix plane state out-of-bounds access For drm_plane_funcs callbacks, it was fixed to use meson specific functions except reset callback. Not like other meson specific callbacks, reset callback allocates drm_plane_state, so accessing meson_plane_state from drm_plane state in other callbacks causes out-of-bounds access. Fix plane state out-of-bounds access by using meson specific reset callback using meson_plane_state based on drm_atomic_helper_plane_reset(). This removes below kasan warning: BUG: KASAN: slab-out-of-bounds in kmemdup+0x4c/0xb0 Read of size 128 at addr ffffffc005a710c0 by task enlightenment/4376 ... [] kmemdup+0x4c/0xb0 [] meson_plane_duplicate_state+0x40/0x90 [] drm_atomic_get_plane_state+0xc4/0x230 [] __drm_atomic_helper_set_config+0xdc/0x788 [] drm_atomic_helper_set_config+0xdc/0x178 [] meson_crtc_set_mode+0x40/0x68 [] drm_mode_set_config_internal+0xf4/0x348 [] drm_mode_setcrtc+0x1d4/0x910 ... Allocated by task 1: ... kmem_cache_alloc_trace+0x20c/0x6c8 drm_atomic_helper_plane_reset+0x6c/0xc8 drm_mode_config_reset+0x7c/0x310 am_meson_drm_bind+0x1fc/0x2f8 try_to_bring_up_master.part.1+0x70/0x128 component_master_add_with_match+0x1b8/0x230 am_meson_drv_probe+0x3c8/0x410 ... Change-Id: Ie7bfd41d797a0782cffa45801629981c25b01561 Fixes commit 1f1efcfdd85d ("drm: add multi-layer support [1/1]") Signed-off-by: Seung-Woo Kim --- diff --git a/drivers/amlogic/drm/meson_plane.c b/drivers/amlogic/drm/meson_plane.c index c7a2d079b9ad..08270f1c7197 100644 --- a/drivers/amlogic/drm/meson_plane.c +++ b/drivers/amlogic/drm/meson_plane.c @@ -292,6 +292,27 @@ meson_plane_duplicate_state(struct drm_plane *plane) return &meson_plane_state->base; } +static void meson_plane_reset(struct drm_plane *plane) +{ + struct am_meson_plane_state *meson_plane_state; + + if (plane->state) { + __drm_atomic_helper_plane_destroy_state(plane->state); + + meson_plane_state = to_am_meson_plane_state(plane->state); + kfree(meson_plane_state); + plane->state = NULL; + } + + meson_plane_state = kzalloc(sizeof(*meson_plane_state), GFP_KERNEL); + + if (meson_plane_state) { + plane->state = &meson_plane_state->base; + plane->state->plane = plane; + plane->state->rotation = DRM_ROTATE_0; + } +} + static void meson_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state) { @@ -336,7 +357,7 @@ static const struct drm_plane_funcs am_osd_plane_funs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, .destroy = drm_plane_cleanup, - .reset = drm_atomic_helper_plane_reset, + .reset = meson_plane_reset, .atomic_duplicate_state = meson_plane_duplicate_state, .atomic_destroy_state = meson_plane_destroy_state, .atomic_set_property = meson_plane_atomic_set_property,