From 05e2600cb0a4d73b0779cf29512819616252aeeb Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Thu, 19 Jan 2023 16:19:17 +0100 Subject: [PATCH] VT: Bump font size limitation to 64x128 pixels This moves 32x32 font size limitation checking down to drivers, so that fbcon can allow large fonts. We still keep a limitation to 64x128 pixels so as to have a simple bounded allocation for con_font_get and in the userland kbd tool. That glyph size will however be enough to have 128x36 characters on a "16/9 8K display". Signed-off-by: Samuel Thibault Link: https://lore.kernel.org/r/20230119151935.112415738@ens-lyon.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt.c | 28 ++++++++++++++++------------ drivers/video/console/vgacon.c | 2 +- drivers/video/fbdev/core/fbcon.c | 2 ++ 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 8da7ab3..57a5c23 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -4523,17 +4523,20 @@ void reset_palette(struct vc_data *vc) /* * Font switching * - * Currently we only support fonts up to 32 pixels wide, at a maximum height - * of 32 pixels. Userspace fontdata is stored with 32 bytes (shorts/ints, - * depending on width) reserved for each character which is kinda wasty, but - * this is done in order to maintain compatibility with the EGA/VGA fonts. It - * is up to the actual low-level console-driver convert data into its favorite - * format (maybe we should add a `fontoffset' field to the `display' - * structure so we won't have to convert the fontdata all the time. + * Currently we only support fonts up to 128 pixels wide, at a maximum height + * of 128 pixels. Userspace fontdata may have to be stored with 32 bytes + * (shorts/ints, depending on width) reserved for each character which is + * kinda wasty, but this is done in order to maintain compatibility with the + * EGA/VGA fonts. It is up to the actual low-level console-driver convert data + * into its favorite format (maybe we should add a `fontoffset' field to the + * `display' structure so we won't have to convert the fontdata all the time. * /Jes */ -#define max_font_size 65536 +#define max_font_width 64 +#define max_font_height 128 +#define max_font_glyphs 512 +#define max_font_size (max_font_glyphs*max_font_width*max_font_height) static int con_font_get(struct vc_data *vc, struct console_font_op *op) { @@ -4543,7 +4546,7 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op) unsigned int vpitch = op->op == KD_FONT_OP_GET_TALL ? op->height : 32; if (op->data) { - font.data = kmalloc(max_font_size, GFP_KERNEL); + font.data = kvmalloc(max_font_size, GFP_KERNEL); if (!font.data) return -ENOMEM; } else @@ -4578,7 +4581,7 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op) rc = -EFAULT; out: - kfree(font.data); + kvfree(font.data); return rc; } @@ -4593,9 +4596,10 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op) return -EINVAL; if (!op->data) return -EINVAL; - if (op->charcount > 512) + if (op->charcount > max_font_glyphs) return -EINVAL; - if (op->width <= 0 || op->width > 32 || !op->height || op->height > 32) + if (op->width <= 0 || op->width > max_font_width || !op->height || + op->height > max_font_height) return -EINVAL; if (vpitch < op->height) return -EINVAL; diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 03c2cce..e25ba52 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1037,7 +1037,7 @@ static int vgacon_font_set(struct vc_data *c, struct console_font *font, if (vga_video_type < VIDEO_TYPE_EGAM) return -EINVAL; - if (font->width != VGA_FONTWIDTH || vpitch != 32 || + if (font->width != VGA_FONTWIDTH || font->height > 32 || vpitch != 32 || (charcount != 256 && charcount != 512)) return -EINVAL; diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 7cd7346..5fb670b 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2279,6 +2279,8 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font, unsigne font->width = vc->vc_font.width; font->height = vc->vc_font.height; + if (font->height > vpitch) + return -ENOSPC; font->charcount = vc->vc_hi_font_mask ? 512 : 256; if (!font->data) return 0; -- 2.7.4