[RFC PATCH v2 05/17] drm/vkms: Avoid reading beyond LUT array

Harry Wentland harry.wentland at amd.com
Thu Oct 19 21:21:21 UTC 2023


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 floot LUT index.

Blurb about LUT creation and how first element should be 0x0 and
last one 0xffff.

Hold on, is that even correct? What should the ends of a LUT be?
How does UNORM work and how does it apply to LUTs?

Signed-off-by: Harry Wentland <harry.wentland at amd.com>
Cc: Ville Syrjala <ville.syrjala at linux.intel.com>
Cc: Pekka Paalanen <pekka.paalanen at collabora.com>
Cc: Simon Ser <contact at emersion.fr>
Cc: Harry Wentland <harry.wentland at amd.com>
Cc: Melissa Wen <mwen at igalia.com>
Cc: Jonas Ådahl <jadahl at redhat.com>
Cc: Sebastian Wick <sebastian.wick at redhat.com>
Cc: Shashank Sharma <shashank.sharma at amd.com>
Cc: Alexander Goins <agoins at nvidia.com>
Cc: Joshua Ashton <joshua at froggi.es>
Cc: Michel Dänzer <mdaenzer at redhat.com>
Cc: Aleix Pol <aleixpol at kde.org>
Cc: Xaver Hugl <xaver.hugl at gmail.com>
Cc: Victoria Brekenfeld <victoria at system76.com>
Cc: Sima <daniel at ffwll.ch>
Cc: Uma Shankar <uma.shankar at intel.com>
Cc: Naseer Ahmed <quic_naseer at quicinc.com>
Cc: Christopher Braga <quic_cbraga at quicinc.com>
Cc: Abhinav Kumar <quic_abhinavk at quicinc.com>
Cc: Arthur Grillo <arthurgrillo at riseup.net>
Cc: Hector Martin <marcan at marcan.st>
Cc: Liviu Dudau <Liviu.Dudau at arm.com>
Cc: Sasha McIntosh <sashamcintosh at google.com>
---
 drivers/gpu/drm/vkms/vkms_composer.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
index a0a3a6fd2926..cf1dff162920 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -123,6 +123,8 @@ 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
@@ -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);
 
-	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);
-- 
2.42.0



More information about the wayland-devel mailing list