Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] Unvalidated device tree coordinates cause out-of-bounds memory accesses in the framebuffer.
- [High] DT logo placement logic ignores SMP logo count and extra logos, breaking centering and overlapping extra logos.
- [High] fb_logo_dt_reserve() calculates logical console space reservations using the incorrect physical axis during screen rotation.
- [High] Overriding logo rotation via device tree breaks the reservation coordinate space contract with fbcon.
- [Medium] TOC-TOU initialization race on `read_done` static flag in `fb_logo_dt_read`.
--
--- Patch [3]: [PATCH v2 3/6] fbdev: honour the device tree boot logo placement properties ---
commit bd67300c4f145f9b35c28ceac495f14e402f271d
Author: Max Pedraza <[email protected]>
fbdev: honour the device tree boot logo placement properties
A logo supplied by the device tree describes a specific product, so where
it lands on the panel matters in a way it does not for the built-in Tux.
Honour the optional "logo-position", "logo-offset", "logo-centered" and
"logo-rotation" properties of the "linux,boot-logo-clut224" node.
> diff --git a/drivers/video/fbdev/core/fb_logo.c b/drivers/video/fbdev/core/fb_logo.c
> --- a/drivers/video/fbdev/core/fb_logo.c
> +++ b/drivers/video/fbdev/core/fb_logo.c
> @@ -2,12 +2,178 @@
>
> #include <linux/fb.h>
> #include <linux/linux_logo.h>
> +#include <linux/of.h>
[ ... ]
> +static void fb_logo_dt_read(void)
> +{
> + struct fb_logo_dt_placement *p = &fb_logo_dt;
> + static bool read_done;
> + struct device_node *np;
> + const char *rotation;
> + u32 val[2];
> + int rot;
> +
> + if (read_done)
> + return;
> +
> + read_done = true;
> +
> + np = of_find_compatible_node(NULL, NULL, "linux,boot-logo-clut224");
[Severity: Medium]
Could this lead to a race condition if called concurrently?
By setting read_done to true before the fb_logo_dt structure is actually
populated, could another thread see read_done as true and proceed to use an
uninitialized structure?
[ ... ]
> +/* Top edge of the logo, in the coordinate space the caller works in */
> +static int fb_logo_dt_top(unsigned int yres, unsigned int logo_height)
> +{
> + struct fb_logo_dt_placement *p = &fb_logo_dt;
> + int top;
> +
> + if (p->centered)
> + top = ((int)yres - (int)logo_height) / 2;
> + else if (p->has_position)
> + top = p->y;
> + else
> + top = 0;
> +
> + return max(top + p->offset_y, 0);
> +}
[Severity: High]
When the screen is hardware-rotated (for example, CW or CCW), does returning
the physical Y coordinate here result in a broken reservation geometry?
fb_prepare_logo() needs the reservation height in the logical coordinate space
of the console. When rotated, the console's logical vertical axis maps to the
hardware's horizontal X-axis, but this logic unconditionally uses the physical
Y position (p->y).
> +static void fb_logo_dt_place(struct fb_info *info, struct fb_image *image)
> +{
> + struct fb_logo_dt_placement *p = &fb_logo_dt;
> + int dx;
> +
> + fb_logo_dt_read();
> +
> + if (!p->valid)
> + return;
> +
> + if (p->centered)
> + dx = ((int)info->var.xres - (int)image->width) / 2;
> + else if (p->has_position)
> + dx = p->x;
> + else
> + dx = image->dx;
> +
> + image->dx = max(dx + p->offset_x, 0);
> + image->dy = fb_logo_dt_top(info->var.yres, image->height);
> +}
[Severity: High]
Does this logic break the centering of SMP logos and the vertical stacking of
extra logos?
When rendering multiple logos, fb_show_logo_line() calculates a block-centered
X coordinate for the SMP penguins and an accumulated Y coordinate to stack any
extra logos.
By calculating dx using only a single image->width, this seems to break SMP
block centering. Additionally, overwriting image->dy with a static position
forces all subsequent extra logos to render at the exact same vertical position
causing them to overlap.
[Severity: High]
Can these unvalidated device tree coordinates cause an out-of-bounds memory
access in the framebuffer?
fb_logo_dt_place() applies the device tree positions directly to image->dx
and image->dy without clamping them to the actual screen dimensions.
If a large offset is provided, would fb_do_show_logo() process the unvalidated
Y coordinate? For example, in the FB_ROTATE_UR case:
for (x = 0;
x < num && image->dx + image->width <= info->var.xres;
x++) {
info->fbops->fb_imageblit(info, image);
The loop checks the X bounds but lacks checks for image->dy + image->height
against info->var.yres, potentially passing arbitrarily large Y coordinates
to the driver's fb_imageblit callback.
[ ... ]
> @@ -423,6 +592,8 @@ int fb_prepare_logo(struct fb_info *info, int rotate)
>
> memset(&fb_logo, 0, sizeof(struct logo_data));
>
> + rotate = fb_logo_dt_rotation(rotate);
> +
> if (info->flags & FBINFO_MISC_TILEBLITTING ||
> info->fbops->owner || !fb_logo_count)
> return 0;
[Severity: High]
Does overriding the caller's rotation parameter here break the coordinate space
agreement with the fbcon subsystem?
The fbcon subsystem calls fb_prepare_logo() with its own console rotation state
and expects the returned reservation height to scale accurately against its
logical vertical axis. If fb_logo_dt_rotation() overrides this with a
differing rotation from the device tree, will fbcon incorrectly interpret the
resulting reservation height against its differing logical axis?
--
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=3
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.