On Tue, 28 Jul 2026, Mallesh Koujalagi <[email protected]> wrote:
> event_string[] has a fixed size of WEDGE_STR_LEN (32) bytes.
> The original scnprintf()-based loop required a manual pre-flight
> bounds check.
>
> Replace the manual bookkeeping with seq_buf, which tracks overflow
> internally. seq_buf_printf() writes each "method," token into the
> buffer, and seq_buf_has_overflowed() detects truncation immediately
> after the write that caused it — using drm_WARN_ONCE() to report it.
>
> On overflow, len retains the position of the last
> successful write, so the trailing comma is stripped cleanly without
> including any partial method name in the uevent payload.
>
> Fixes: b7cf9f4ac1b8 ("drm: Introduce device wedged event")
> Signed-off-by: Mallesh Koujalagi <[email protected]>
> ---
> v2:
> - Add proper logic to handle recovery string. (Raag)
>
> v3:
> - Convert manual bounds check to seq_buf. (Jani Nikula)
> - Use drm_WARN_ONCE() instead of drm_WARN_ON() for overflow. (Raag)
> ---
>  drivers/gpu/drm/drm_drv.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index e51ed959da89..6a5e3fa1350c 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -36,6 +36,7 @@
>  #include <linux/mount.h>
>  #include <linux/pseudo_fs.h>
>  #include <linux/sched.h>
> +#include <linux/seq_buf.h>
>  #include <linux/slab.h>
>  #include <linux/sprintf.h>
>  #include <linux/srcu.h>
> @@ -578,15 +579,22 @@ int drm_dev_wedged_event(struct drm_device *dev, 
> unsigned long method,
>       char *envp[] = { event_string, NULL, NULL, NULL };
>       const char *recovery = NULL;
>       unsigned int len, opt;
> +     struct seq_buf buf;
>  
> -     len = scnprintf(event_string, sizeof(event_string), "%s", "WEDGED=");
> +     seq_buf_init(&buf, event_string, sizeof(event_string));

See DECLARE_SEQ_BUF(). Remove event_string altogether (or make that the
seq_buf name).

> +     seq_buf_puts(&buf, "WEDGED=");
> +     len = seq_buf_used(&buf);

Why do you need to keep len around?

>  
>       for_each_set_bit(opt, &method, BITS_PER_TYPE(method)) {
>               recovery = drm_get_wedge_recovery(opt);
>               if (drm_WARN_ONCE(dev, !recovery, "invalid recovery method 
> %u\n", opt))
>                       break;
>  
> -             len += scnprintf(event_string + len, sizeof(event_string) - 
> len, "%s,", recovery);
> +             seq_buf_printf(&buf, "%s,", recovery);
> +             if (drm_WARN_ONCE(dev, seq_buf_has_overflowed(&buf),
> +                               "WEDGED event string truncated\n"))
> +                     break;

Nah, you can keep printing to seq_buf, and only check at the end once
instead of looping.

> +             len = seq_buf_used(&buf);
>       }
>  
>       if (recovery)

-- 
Jani Nikula, Intel

Reply via email to