From: Harry Wentland <[email protected]>
[Why]
dp_link_settings_read() passed strlen() of each format string as the size
argument to snprintf() and then advanced rd_buf_ptr by that same fixed amount.
The format-string length has no relation to the formatted output length, so
snprintf() truncated each field at a NUL it wrote inside the buffer while the
pointer was advanced past it. The result is a buffer peppered with embedded NUL
bytes and fields that are silently cut short, so the data read back from the
debugfs node does not reflect the actual link settings.
[How]
Use scnprintf() with the real remaining buffer size
(rd_buf_size - (rd_buf_ptr - rd_buf)) and advance rd_buf_ptr by its return
value, which is the number of characters actually written. This both bounds
each write to the space left in rd_buf and keeps the output a single,
properly terminated string. The now-unused str_len local is removed.
Fixes: 41db5f1931ec ("drm/amd/display: set-read link rate and lane count
through debugfs")
Cc: [email protected]
Assisted-by: Copilot:claude-opus-4.8
Reviewed-by: Alex Hung <[email protected]>
Signed-off-by: Harry Wentland <[email protected]>
Signed-off-by: George Zhang <[email protected]>
---
.../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 20 ++++++++-----------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 1f5dde2bc74c..6b07982e3aa5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -196,7 +196,6 @@ static ssize_t dp_link_settings_read(struct file *f, char
__user *buf,
char *rd_buf_ptr = NULL;
const uint32_t rd_buf_size = 100;
uint32_t result = 0;
- uint8_t str_len = 0;
int r;
if (*pos & 3 || size & 3)
@@ -208,29 +207,26 @@ static ssize_t dp_link_settings_read(struct file *f, char
__user *buf,
rd_buf_ptr = rd_buf;
- str_len = strlen("Current: %d 0x%x %d ");
- snprintf(rd_buf_ptr, str_len, "Current: %d 0x%x %d ",
+ rd_buf_ptr += scnprintf(rd_buf_ptr, rd_buf_size - (rd_buf_ptr - rd_buf),
+ "Current: %d 0x%x %d ",
link->cur_link_settings.lane_count,
link->cur_link_settings.link_rate,
link->cur_link_settings.link_spread);
- rd_buf_ptr += str_len;
- str_len = strlen("Verified: %d 0x%x %d ");
- snprintf(rd_buf_ptr, str_len, "Verified: %d 0x%x %d ",
+ rd_buf_ptr += scnprintf(rd_buf_ptr, rd_buf_size - (rd_buf_ptr - rd_buf),
+ "Verified: %d 0x%x %d ",
link->verified_link_cap.lane_count,
link->verified_link_cap.link_rate,
link->verified_link_cap.link_spread);
- rd_buf_ptr += str_len;
- str_len = strlen("Reported: %d 0x%x %d ");
- snprintf(rd_buf_ptr, str_len, "Reported: %d 0x%x %d ",
+ rd_buf_ptr += scnprintf(rd_buf_ptr, rd_buf_size - (rd_buf_ptr - rd_buf),
+ "Reported: %d 0x%x %d ",
link->reported_link_cap.lane_count,
link->reported_link_cap.link_rate,
link->reported_link_cap.link_spread);
- rd_buf_ptr += str_len;
- str_len = strlen("Preferred: %d 0x%x %d ");
- snprintf(rd_buf_ptr, str_len, "Preferred: %d 0x%x %d\n",
+ rd_buf_ptr += scnprintf(rd_buf_ptr, rd_buf_size - (rd_buf_ptr - rd_buf),
+ "Preferred: %d 0x%x %d\n",
link->preferred_link_setting.lane_count,
link->preferred_link_setting.link_rate,
link->preferred_link_setting.link_spread);
--
2.53.0