Thank you for your contribution! Sashiko AI review found 5 potential issue(s) 
to consider:

Pre-existing issues:
- [High] Missing locking in edid_store() leads to data races, double free, and 
memory corruption.
- [High] The patch fails to prevent a Use-After-Free of `fb_info->mode` via 
sysfs attributes.
- [High] The `edid` sysfs attribute is world-writable (0666), enabling 
unprivileged users to exploit multiple driver vulnerabilities.
- [Medium] Repeated calls to `dlfb_setup_modes()` leak the old `dlfb->edid` 
buffer.
- [Medium] Unbounded memory leak of the dynamically allocated 
`info->monspecs.modedb` array.
--

commit c422e1f65727b9cb9b5d809088416cf97c54aea9
Author: Xiang Mei <[email protected]>

fbdev: udlfb: don't rebuild the mode list while the framebuffer is in use

This commit attempts to fix a use-after-free in fb_videomode_to_var() by
checking dlfb->fb_count before destroying the modelist in
dlfb_setup_modes(). This prevents fbcon from referencing a freed mode
list.

Link: 
https://lore.kernel.org/all/1jSCSNaDKmuUG7h40rTsSl1rMaSwdlJef4rp%40bugs.sh/

> diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c
> index e78d6f95c9c5c..92b352bc7e969 100644
> --- a/drivers/video/fbdev/udlfb.c
> +++ b/drivers/video/fbdev/udlfb.c
> @@ -1293,6 +1293,11 @@ static int dlfb_setup_modes(struct dlfb_data *dlfb,
>               goto error;
>       }
>  
> +     if (dlfb->fb_count) {
> +             result = -EINVAL;
> +             goto error;
> +     }
> +
>       fb_destroy_modelist(&info->modelist);

[Severity: High]
This isn't a bug introduced by this patch, but does writing to the mode sysfs
attribute increment dlfb->fb_count?

If an unprivileged user sets fb_info->mode to a node in info->modelist via
fbsysfs.c:store_mode(), and then writes to the edid sysfs attribute,
dlfb->fb_count remains 0. The check above passes, and fb_destroy_modelist()
is executed, leaving fb_info->mode as a dangling pointer.

Subsequent reads from the mode sysfs attribute would invoke show_mode(),
triggering a use-after-free.

>       memset(&info->monspecs, 0, sizeof(info->monspecs));

[Severity: Medium]
This is a pre-existing issue, but does this memset() leak the dynamically
allocated info->monspecs.modedb array?

If fb_edid_to_monspecs() previously parsed the EDID and dynamically allocated
the array of struct fb_videomode, unconditionally zeroing the structure here
appears to erase the pointer before it can be freed, leaking the memory on
every sysfs write.

[Severity: Medium]
While not introduced by this patch, could this leak the old dlfb->edid
buffer?

When dlfb_setup_modes() succeeds:

drivers/video/fbdev/udlfb.c:dlfb_setup_modes() {
    ...
                if (info->monspecs.modedb_len > 0) {
                        dlfb->edid = edid;
                        dlfb->edid_size = i;
                        break;
                }
    ...
}

Does this overwrite dlfb->edid with a newly allocated 128-byte edid buffer
without freeing the previous pointer?


[Severity: High]
This is a pre-existing issue, but is it safe for edid_store() to call
dlfb_ops_set_par() without holding info->lock?

drivers/video/fbdev/udlfb.c:edid_store() {
    ...
        ret = dlfb_ops_set_par(fb_info);
    ...
}

dlfb_ops_set_par() invokes dlfb_realloc_framebuffer() which performs memory
freeing and list_add() operations, explicitly relying on the lock:

drivers/video/fbdev/udlfb.c:dlfb_realloc_framebuffer() {
/*
 * Assumes &info->lock held by caller
 */
static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb,
                                    struct fb_info *info, u32 new_len)
    ...
}

If an unprivileged user concurrently writes to the edid sysfs attribute,
could this lead to data races resulting in a double-free of
info->screen_buffer and list corruption on dlfb->deferred_free?


[Severity: High]
Finally, as a pre-existing issue, should the edid sysfs attribute be
world-writable?

drivers/video/fbdev/udlfb.c:edid_attr {
static const struct bin_attribute edid_attr = {
        .attr.name = "edid",
        .attr.mode = 0666,
        .size = EDID_LENGTH,
        .read = edid_show,
        .write = edid_store
};
}

This 0666 permission allows any unprivileged user to alter the physical
display configuration, and easily trigger the memory leaks, double frees,
and use-after-free vulnerabilities mentioned above.

-- 
Sashiko AI review ยท 
https://sashiko.dev/#/patchset/[email protected]?part=1

Reply via email to