[PATCH] drm/dp: Validate the I2C-over-AUX speed parameter

From: Yingjie Wang

Date: Fri Oct 23 2026 - 08:42:49 EST


The dp_aux_i2c_speed_khz parameter is documented to accept values from
1 through 400, but its generic signed integer setter accepts any integer.

drm_dp_i2c_msg_duration() uses the parameter as a divisor when
estimating the I2C-over-AUX transfer duration. Setting the parameter to
zero can therefore trigger a division by zero when calculating the retry
count for an I2C-over-AUX transfer.

Use an unsigned min/max parameter setter to enforce the documented
range at load time and on runtime writes. Valid values retain their
existing behavior. Retain the parameter type in the module metadata.

A software DP AUX adapter reproduced the divide error without display
hardware. With this change on an x86_64 KASAN build, runtime writes of
-1, 0, and 401 are rejected. Values 1 and 400 are accepted and complete
an I2C-over-AUX transfer. A boot-time value of 0 is rejected and 400 is
accepted.

An automated audit of writable runtime parameters identified this
issue. Codex was used to analyze the bug, prepare the change, and draft
this changelog.

Fixes: f36203be608a ("drm/dp: Add dp_aux_i2c_speed_khz module param to set the assume i2c bus speed")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Yingjie Wang <1075151112@xxxxxx>
---
drivers/gpu/drm/display/drm_dp_helper.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
index 488fd123a01ad..53fdaa7b59275 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -1975,8 +1975,22 @@ static int drm_dp_i2c_retry_count(const struct drm_dp_aux_msg *msg,
* FIXME currently assumes 10 kHz as some real world devices seem
* to require it. We should query/set the speed via DPCD if supported.
*/
-static int dp_aux_i2c_speed_khz __read_mostly = 10;
-module_param_unsafe(dp_aux_i2c_speed_khz, int, 0644);
+static unsigned int dp_aux_i2c_speed_khz __read_mostly = 10;
+
+static int dp_aux_i2c_speed_khz_set(const char *val,
+ const struct kernel_param *kp)
+{
+ return param_set_uint_minmax(val, kp, 1, 400);
+}
+
+static const struct kernel_param_ops dp_aux_i2c_speed_khz_ops = {
+ .set = dp_aux_i2c_speed_khz_set,
+ .get = param_get_uint,
+};
+
+module_param_cb_unsafe(dp_aux_i2c_speed_khz, &dp_aux_i2c_speed_khz_ops,
+ &dp_aux_i2c_speed_khz, 0644);
+__MODULE_PARM_TYPE(dp_aux_i2c_speed_khz, "uint");
MODULE_PARM_DESC(dp_aux_i2c_speed_khz,
"Assumed speed of the i2c bus in kHz, (1-400, default 10)");


base-commit: 734bef548a96e8774d6eef5dfa2026c6edc4e80b
--
2.43.0