Commit 2fee8403 authored by Harry Wentland's avatar Harry Wentland Committed by Melissa Wen

drm/vkms: Avoid reading beyond LUT array

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: db1f254f ("drm/vkms: Add support to 1D gamma LUT")
Signed-off-by: default avatarHarry Wentland <harry.wentland@amd.com>
Cc: Arthur Grillo <arthurgrillo@riseup.net>
Reviewed-by: default avatarArthur Grillo <arthurgrillo@riseup.net>
Reviewed-by: default avatarMelissa Wen <mwen@igalia.com>
Signed-off-by: default avatarMelissa Wen <melissa.srw@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231108163647.106853-6-harry.wentland@amd.com
parent ffcc67cd
...@@ -123,6 +123,8 @@ static u16 apply_lut_to_channel_value(const struct vkms_color_lut *lut, u16 chan ...@@ -123,6 +123,8 @@ static u16 apply_lut_to_channel_value(const struct vkms_color_lut *lut, u16 chan
enum lut_channel channel) enum lut_channel channel)
{ {
s64 lut_index = get_lut_index(lut, channel_value); 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 * This checks if `struct drm_color_lut` has any gap added by the compiler
...@@ -130,11 +132,15 @@ static u16 apply_lut_to_channel_value(const struct vkms_color_lut *lut, u16 chan ...@@ -130,11 +132,15 @@ static u16 apply_lut_to_channel_value(const struct vkms_color_lut *lut, u16 chan
*/ */
static_assert(sizeof(struct drm_color_lut) == sizeof(__u16) * 4); static_assert(sizeof(struct drm_color_lut) == sizeof(__u16) * 4);
u16 *floor_lut_value = (__u16 *)&lut->base[drm_fixp2int(lut_index)]; floor_lut_value = (__u16 *)&lut->base[drm_fixp2int(lut_index)];
u16 *ceil_lut_value = (__u16 *)&lut->base[drm_fixp2int_ceil(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]; floor_channel_value = floor_lut_value[channel];
u16 ceil_channel_value = ceil_lut_value[channel]; ceil_channel_value = ceil_lut_value[channel];
return lerp_u16(floor_channel_value, ceil_channel_value, return lerp_u16(floor_channel_value, ceil_channel_value,
lut_index & DRM_FIXED_DECIMAL_MASK); lut_index & DRM_FIXED_DECIMAL_MASK);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment