summary refs log tree commit diff
path: root/drivers/video/fbdev/core
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-08-26 10:58:20 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2020-08-26 10:58:20 -0700
commit15bc20c6af4ceee97a1f90b43c0e386643c071b4 (patch)
tree9d17d72e80a14552eda45027faaa2330ef6a2857 /drivers/video/fbdev/core
parent27563ab6ef75abc64b7da2c7a321b7edd89dfcf7 (diff)
parentea1fc02e12b647d8dd7515d1dba137847d8e951d (diff)
downloadlinux-15bc20c6af4ceee97a1f90b43c0e386643c071b4.tar.gz
Merge tag 'tty-5.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial fixes from Greg KH:
 "Here are a few small TTY/Serial/vt fixes for 5.9-rc3

  Included in here are:
   - qcom serial fixes
   - vt ioctl and core bugfixes
   - pl011 serial driver fixes
   - 8250 serial driver fixes
   - other misc serial driver fixes

  and for good measure:
   - fbcon fix for syzbot found problem.

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'tty-5.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  tty: serial: imx: add dependence and build for earlycon
  serial: samsung: Removes the IRQ not found warning
  serial: 8250: change lock order in serial8250_do_startup()
  serial: stm32: avoid kernel warning on absence of optional IRQ
  serial: pl011: Fix oops on -EPROBE_DEFER
  serial: pl011: Don't leak amba_ports entry on driver register error
  serial: 8250_exar: Fix number of ports for Commtech PCIe cards
  tty: serial: qcom_geni_serial: Drop __init from qcom_geni_console_setup
  serial: qcom_geni_serial: Fix recent kdb hang
  vt_ioctl: change VT_RESIZEX ioctl to check for error return from vc_resize()
  fbcon: prevent user font height or width change from causing potential out-of-bounds access
  vt: defer kfree() of vc_screenbuf in vc_do_resize()
Diffstat (limited to 'drivers/video/fbdev/core')
-rw-r--r--drivers/video/fbdev/core/fbcon.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 8a31fc2b2258..66167830fefd 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -2191,6 +2191,9 @@ static void updatescrollmode(struct fbcon_display *p,
 	}
 }
 
+#define PITCH(w) (((w) + 7) >> 3)
+#define CALC_FONTSZ(h, p, c) ((h) * (p) * (c)) /* size = height * pitch * charcount */
+
 static int fbcon_resize(struct vc_data *vc, unsigned int width, 
 			unsigned int height, unsigned int user)
 {
@@ -2200,6 +2203,24 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
 	struct fb_var_screeninfo var = info->var;
 	int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh;
 
+	if (ops->p && ops->p->userfont && FNTSIZE(vc->vc_font.data)) {
+		int size;
+		int pitch = PITCH(vc->vc_font.width);
+
+		/*
+		 * If user font, ensure that a possible change to user font
+		 * height or width will not allow a font data out-of-bounds access.
+		 * NOTE: must use original charcount in calculation as font
+		 * charcount can change and cannot be used to determine the
+		 * font data allocated size.
+		 */
+		if (pitch <= 0)
+			return -EINVAL;
+		size = CALC_FONTSZ(vc->vc_font.height, pitch, FNTCHARCNT(vc->vc_font.data));
+		if (size > FNTSIZE(vc->vc_font.data))
+			return -EINVAL;
+	}
+
 	virt_w = FBCON_SWAP(ops->rotate, width, height);
 	virt_h = FBCON_SWAP(ops->rotate, height, width);
 	virt_fw = FBCON_SWAP(ops->rotate, vc->vc_font.width,
@@ -2652,7 +2673,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font,
 	int size;
 	int i, csum;
 	u8 *new_data, *data = font->data;
-	int pitch = (font->width+7) >> 3;
+	int pitch = PITCH(font->width);
 
 	/* Is there a reason why fbconsole couldn't handle any charcount >256?
 	 * If not this check should be changed to charcount < 256 */
@@ -2668,7 +2689,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font,
 	if (fbcon_invalid_charcount(info, charcount))
 		return -EINVAL;
 
-	size = h * pitch * charcount;
+	size = CALC_FONTSZ(h, pitch, charcount);
 
 	new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER);