From 1f43b1412799b6d0305d7f9af0d81ef57d586e2e Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Fri, 2 May 2025 11:29:01 -0400 Subject: [PATCH] linux-fbdev: Don't overrun the framebuffer when it's larger than expected We expect a fixed FRAMEBUFFER_SIZE that's width*height*bitdepth, and we mmap()ed that in. However, when doing the initial fb clear, we were using the hardware-provided 'finfo.smem_len' which could be larger than FRAMEBUFFER_SIZE. This overran our mmap and triggered a segfault. Correct this by mmaping (and clearing) the entire smem_len. As a safety measure, panic if smem_len is smaller than our expected FRAMEBUFFER_SIZE Change-Id: I3222139c7aed6e8e8ee232b1730edd5cd70065ff --- firmware/target/hosted/lcd-linuxfb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/firmware/target/hosted/lcd-linuxfb.c b/firmware/target/hosted/lcd-linuxfb.c index 5dda5cf1cc..c0eaf07fb4 100644 --- a/firmware/target/hosted/lcd-linuxfb.c +++ b/firmware/target/hosted/lcd-linuxfb.c @@ -69,6 +69,7 @@ void lcd_init_device(void) vinfo.bits_per_pixel = LCD_DEPTH; vinfo.xres = LCD_WIDTH; vinfo.yres = LCD_HEIGHT; + vinfo.yres_virtual = vinfo.yres; /* Ensure we're on the correct bank */ if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo)) { panicf("Cannot set framebuffer to %dx%dx%d", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel); @@ -76,9 +77,11 @@ void lcd_init_device(void) } /* Note: we use a framebuffer size of width*height*bbp. We cannot trust the * values returned by the driver for line_length */ + if (finfo.smem_len < FRAMEBUFFER_SIZE) + panicf("FRAMEBUFFER_SIZE too large for hardware? (%u vs %u)", FRAMEBUFFER_SIZE, finfo.smem_len); /* map framebuffer */ - framebuffer = mmap(NULL, FRAMEBUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + framebuffer = mmap(NULL, finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if((void *)framebuffer == MAP_FAILED) { panicf("Cannot map framebuffer");