Skip to content

Commit

Permalink
drm/vkms: Avoid reading beyond LUT array
Browse files Browse the repository at this point in the history
[ Upstream commit 2fee84030d12d9fddfa874e4562d71761a129277 ]

When the floor LUT index (drm_fixp2int(lut_index) is the last
index of the array the ceil LUT index will point to an entry
beyond the array. Make sure we guard against it and use the
value of the floor LUT index.

v3:
 - Drop bits from commit description that didn't contribute
   anything of value

Fixes: db1f254 ("drm/vkms: Add support to 1D gamma LUT")
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Cc: Arthur Grillo <arthurgrillo@riseup.net>
Reviewed-by: Arthur Grillo <arthurgrillo@riseup.net>
Reviewed-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <melissa.srw@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231108163647.106853-6-harry.wentland@amd.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Harry Wentland authored and Sasha Levin committed Mar 26, 2024
1 parent bac3d37 commit 9556c16
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions drivers/gpu/drm/vkms/vkms_composer.c
Expand Up @@ -123,18 +123,24 @@ static u16 apply_lut_to_channel_value(const struct vkms_color_lut *lut, u16 chan
enum lut_channel channel)
{
s64 lut_index = get_lut_index(lut, channel_value);
u16 *floor_lut_value, *ceil_lut_value;
u16 floor_channel_value, ceil_channel_value;

/*
* This checks if `struct drm_color_lut` has any gap added by the compiler
* between the struct fields.
*/
static_assert(sizeof(struct drm_color_lut) == sizeof(__u16) * 4);

u16 *floor_lut_value = (__u16 *)&lut->base[drm_fixp2int(lut_index)];
u16 *ceil_lut_value = (__u16 *)&lut->base[drm_fixp2int_ceil(lut_index)];
floor_lut_value = (__u16 *)&lut->base[drm_fixp2int(lut_index)];
if (drm_fixp2int(lut_index) == (lut->lut_length - 1))
/* We're at the end of the LUT array, use same value for ceil and floor */
ceil_lut_value = floor_lut_value;
else
ceil_lut_value = (__u16 *)&lut->base[drm_fixp2int_ceil(lut_index)];

u16 floor_channel_value = floor_lut_value[channel];
u16 ceil_channel_value = ceil_lut_value[channel];
floor_channel_value = floor_lut_value[channel];
ceil_channel_value = ceil_lut_value[channel];

return lerp_u16(floor_channel_value, ceil_channel_value,
lut_index & DRM_FIXED_DECIMAL_MASK);
Expand Down

0 comments on commit 9556c16

Please sign in to comment.