Takashi Iwai 01c63d
From 3c4e0dff2095c579b142d5a0693257f1c58b4804 Mon Sep 17 00:00:00 2001
Takashi Iwai 01c63d
From: Daniel Vetter <daniel.vetter@ffwll.ch>
Takashi Iwai 01c63d
Date: Sun, 8 Nov 2020 16:38:06 +0100
Takashi Iwai 01c63d
Subject: [PATCH] vt: Disable KD_FONT_OP_COPY
Takashi Iwai 01c63d
Git-commit: 3c4e0dff2095c579b142d5a0693257f1c58b4804
Takashi Iwai 01c63d
Patch-mainline: v5.10-rc3
Takashi Iwai 01c63d
References: bsc#1178589
Takashi Iwai 01c63d
Takashi Iwai 01c63d
It's buggy:
Takashi Iwai 01c63d
Takashi Iwai 01c63d
On Fri, Nov 06, 2020 at 10:30:08PM +0800, Minh Yuan wrote:
Takashi Iwai 01c63d
> We recently discovered a slab-out-of-bounds read in fbcon in the latest
Takashi Iwai 01c63d
> kernel ( v5.10-rc2 for now ).  The root cause of this vulnerability is that
Takashi Iwai 01c63d
> "fbcon_do_set_font" did not handle "vc->vc_font.data" and
Takashi Iwai 01c63d
> "vc->vc_font.height" correctly, and the patch
Takashi Iwai 01c63d
> <https://lkml.org/lkml/2020/9/27/223> for VT_RESIZEX can't handle this
Takashi Iwai 01c63d
> issue.
Takashi Iwai 01c63d
>
Takashi Iwai 01c63d
> Specifically, we use KD_FONT_OP_SET to set a small font.data for tty6, and
Takashi Iwai 01c63d
> use  KD_FONT_OP_SET again to set a large font.height for tty1. After that,
Takashi Iwai 01c63d
> we use KD_FONT_OP_COPY to assign tty6's vc_font.data to tty1's vc_font.data
Takashi Iwai 01c63d
> in "fbcon_do_set_font", while tty1 retains the original larger
Takashi Iwai 01c63d
> height. Obviously, this will cause an out-of-bounds read, because we can
Takashi Iwai 01c63d
> access a smaller vc_font.data with a larger vc_font.height.
Takashi Iwai 01c63d
Takashi Iwai 01c63d
Further there was only one user ever.
Takashi Iwai 01c63d
- Android's loadfont, busybox and console-tools only ever use OP_GET
Takashi Iwai 01c63d
  and OP_SET
Takashi Iwai 01c63d
- fbset documentation only mentions the kernel cmdline font: option,
Takashi Iwai 01c63d
  not anything else.
Takashi Iwai 01c63d
- systemd used OP_COPY before release 232 published in Nov 2016
Takashi Iwai 01c63d
Takashi Iwai 01c63d
Now unfortunately the crucial report seems to have gone down with
Takashi Iwai 01c63d
gmane, and the commit message doesn't say much. But the pull request
Takashi Iwai 01c63d
hints at OP_COPY being broken
Takashi Iwai 01c63d
Takashi Iwai 01c63d
https://github.com/systemd/systemd/pull/3651
Takashi Iwai 01c63d
Takashi Iwai 01c63d
So in other words, this never worked, and the only project which
Takashi Iwai 01c63d
foolishly every tried to use it, realized that rather quickly too.
Takashi Iwai 01c63d
Takashi Iwai 01c63d
Instead of trying to fix security issues here on dead code by adding
Takashi Iwai 01c63d
missing checks, fix the entire thing by removing the functionality.
Takashi Iwai 01c63d
Takashi Iwai 01c63d
Note that systemd code using the OP_COPY function ignored the return
Takashi Iwai 01c63d
value, so it doesn't matter what we're doing here really - just in
Takashi Iwai 01c63d
case a lone server somewhere happens to be extremely unlucky and
Takashi Iwai 01c63d
running an affected old version of systemd. The relevant code from
Takashi Iwai 01c63d
font_copy_to_all_vcs() in systemd was:
Takashi Iwai 01c63d
Takashi Iwai 01c63d
	/* copy font from active VT, where the font was uploaded to */
Takashi Iwai 01c63d
	cfo.op = KD_FONT_OP_COPY;
Takashi Iwai 01c63d
	cfo.height = vcs.v_active-1; /* tty1 == index 0 */
Takashi Iwai 01c63d
	(void) ioctl(vcfd, KDFONTOP, &cfo;;
Takashi Iwai 01c63d
Takashi Iwai 01c63d
Note this just disables the ioctl, garbage collecting the now unused
Takashi Iwai 01c63d
callbacks is left for -next.
Takashi Iwai 01c63d
Takashi Iwai 01c63d
V2: Tetsuo found the old mail, which allowed me to find it on another
Takashi Iwai 01c63d
archive. Add the link too.
Takashi Iwai 01c63d
Takashi Iwai 01c63d
Acked-by: Peilin Ye <yepeilin.cs@gmail.com>
Takashi Iwai 01c63d
Reported-by: Minh Yuan <yuanmingbuaa@gmail.com>
Takashi Iwai 01c63d
References: https://lists.freedesktop.org/archives/systemd-devel/2016-June/036935.html
Takashi Iwai 01c63d
References: https://github.com/systemd/systemd/pull/3651
Takashi Iwai 01c63d
Cc: Greg KH <greg@kroah.com>
Takashi Iwai 01c63d
Cc: Peilin Ye <yepeilin.cs@gmail.com>
Takashi Iwai 01c63d
Cc: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Takashi Iwai 01c63d
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Takashi Iwai 01c63d
Link: https://lore.kernel.org/r/20201108153806.3140315-1-daniel.vetter@ffwll.ch
Takashi Iwai 01c63d
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Takashi Iwai 01c63d
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 01c63d
Takashi Iwai 01c63d
---
Takashi Iwai 01c63d
 drivers/tty/vt/vt.c | 24 ++----------------------
Takashi Iwai 01c63d
 1 file changed, 2 insertions(+), 22 deletions(-)
Takashi Iwai 01c63d
Takashi Iwai 01c63d
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
Takashi Iwai 01c63d
index 9506a76f3ab6..d04a162939a4 100644
Takashi Iwai 01c63d
--- a/drivers/tty/vt/vt.c
Takashi Iwai 01c63d
+++ b/drivers/tty/vt/vt.c
Takashi Iwai 01c63d
@@ -4704,27 +4704,6 @@ static int con_font_default(struct vc_data *vc, struct console_font_op *op)
Takashi Iwai 01c63d
 	return rc;
Takashi Iwai 01c63d
 }
Takashi Iwai 01c63d
 
Takashi Iwai 01c63d
-static int con_font_copy(struct vc_data *vc, struct console_font_op *op)
Takashi Iwai 01c63d
-{
Takashi Iwai 01c63d
-	int con = op->height;
Takashi Iwai 01c63d
-	int rc;
Takashi Iwai 01c63d
-
Takashi Iwai 01c63d
-
Takashi Iwai 01c63d
-	console_lock();
Takashi Iwai 01c63d
-	if (vc->vc_mode != KD_TEXT)
Takashi Iwai 01c63d
-		rc = -EINVAL;
Takashi Iwai 01c63d
-	else if (!vc->vc_sw->con_font_copy)
Takashi Iwai 01c63d
-		rc = -ENOSYS;
Takashi Iwai 01c63d
-	else if (con < 0 || !vc_cons_allocated(con))
Takashi Iwai 01c63d
-		rc = -ENOTTY;
Takashi Iwai 01c63d
-	else if (con == vc->vc_num)	/* nothing to do */
Takashi Iwai 01c63d
-		rc = 0;
Takashi Iwai 01c63d
-	else
Takashi Iwai 01c63d
-		rc = vc->vc_sw->con_font_copy(vc, con);
Takashi Iwai 01c63d
-	console_unlock();
Takashi Iwai 01c63d
-	return rc;
Takashi Iwai 01c63d
-}
Takashi Iwai 01c63d
-
Takashi Iwai 01c63d
 int con_font_op(struct vc_data *vc, struct console_font_op *op)
Takashi Iwai 01c63d
 {
Takashi Iwai 01c63d
 	switch (op->op) {
Takashi Iwai 01c63d
@@ -4735,7 +4714,8 @@ int con_font_op(struct vc_data *vc, struct console_font_op *op)
Takashi Iwai 01c63d
 	case KD_FONT_OP_SET_DEFAULT:
Takashi Iwai 01c63d
 		return con_font_default(vc, op);
Takashi Iwai 01c63d
 	case KD_FONT_OP_COPY:
Takashi Iwai 01c63d
-		return con_font_copy(vc, op);
Takashi Iwai 01c63d
+		/* was buggy and never really used */
Takashi Iwai 01c63d
+		return -EINVAL;
Takashi Iwai 01c63d
 	}
Takashi Iwai 01c63d
 	return -ENOSYS;
Takashi Iwai 01c63d
 }
Takashi Iwai 01c63d
-- 
Takashi Iwai 01c63d
2.16.4
Takashi Iwai 01c63d