Re: [RFC PATCH] fbcon: Fix out-of-bounds memory in fbcon_putcs

From: chenjun (AM)

Date: Fri Feb 27 2026 - 09:55:33 EST


在 2026/2/27 22:50, chenjun (AM) 写道:
> When a font is set on an invisible console, the screen will not update.
> However, the fontbuffer is not updated to match the new font dimensions.
>
> This inconsistency leads to out-of-bounds memory access when writing to
> the tty bound to fbcon, as demonstrated by the following KASAN report:
>
> BUG: KASAN: slab-out-of-bounds in fb_pad_aligned_buffer+0xdf/0x140
> Read of size 1 at addr ffff8881195a2280 by task a.out/971
> Call Trace:
> <TASK>
> fb_pad_aligned_buffer+0xdf/0x140
> ud_putcs+0x88a/0xde0
> fbcon_putcs+0x319/0x430
> do_update_region+0x23c/0x3b0
> do_con_write+0x225c/0x67f0
> con_write+0xe/0x30
> n_tty_write+0x4b5/0xff0
> file_tty_write.isra.41+0x46c/0x880
> vfs_write+0x868/0xd60
> ksys_write+0xf2/0x1d0
> do_syscall_64+0xfa/0x570
>
> Fix this by calling fbcon_rotate_font() if vc is invisible in
> fbcon_do_set_font().
>
> Signed-off-by: Chen Jun <chenjun102@xxxxxxxxxx>
> ---
> drivers/video/fbdev/core/fbcon.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
> index 666261ae59d8..d76100188bee 100644
> --- a/drivers/video/fbdev/core/fbcon.c
> +++ b/drivers/video/fbdev/core/fbcon.c
> @@ -2444,6 +2444,11 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,
> rows = FBCON_SWAP(par->rotate, info->var.yres, info->var.xres);
> cols /= w;
> rows /= h;
> + if (!con_is_visible(vc)) {
> + ret = fbcon_rotate_font(info, vc);
> + if (ret)
> + goto err_out;
> + }
> ret = vc_resize(vc, cols, rows);
> if (ret)
> goto err_out;
>

There is a poc:
```
#define _GNU_SOURCE

#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/ioctl.h>

#include <linux/capability.h>

char my_font_data[512 * 1 * 32 * 32];

struct console_font_op {
unsigned int op;
unsigned int flags;
unsigned int width, height;
unsigned int charcount;
unsigned char *data;
};

void execute_one(void)
{
int tty = open("/dev/tty2", O_APPEND|O_RDWR, 0);
char buf[100] = {27, '#', '8', 0xa, 0x5, 0x5, 0x5, 0x5};
struct console_font_op op = {
.op = 0,
.width = 32,
.height = 32,
.charcount = 512,
.data = my_font_data,
};

ioctl(tty, 0x4B72, &op);
write(tty, buf, 100);
}
int main(void)
{
execute_one();
return 0;
}
```
echo 2 > /sys/class/graphics/fbcon/rotate_all
./poc