Message ID | 20220803042030.179067-3-cengiz.can@canonical.com |
---|---|
State | New |
Headers | show |
Series | [SRU,Focal,1/1] vt: drop old FONT ioctls | expand |
On 03.08.22 06:20, Cengiz Can wrote: > From: Jiri Slaby <jslaby@suse.cz> > > commit ff2047fb755d4415ec3c70ac799889371151796d upstream. > > Drop support for these ioctls: > * PIO_FONT, PIO_FONTX > * GIO_FONT, GIO_FONTX > * PIO_FONTRESET > > As was demonstrated by commit 90bfdeef83f1 (tty: make FONTX ioctl use > the tty pointer they were actually passed), these ioctls are not used > from userspace, as: > 1) they used to be broken (set up font on current console, not the open > one) and racy (before the commit above) > 2) KDFONTOP ioctl is used for years instead > > Note that PIO_FONTRESET is defunct on most systems as VGA_CONSOLE is set > on them for ages. That turns on BROKEN_GRAPHICS_PROGRAMS which makes > PIO_FONTRESET just return an error. > > We are removing KD_FONT_FLAG_OLD here as it was used only by these > removed ioctls. kd.h header exists both in kernel and uapi headers, so > we can remove the kernel one completely. Everyone includeing kd.h will > now automatically get the uapi one. > > There are now unused definitions of the ioctl numbers and "struct > consolefontdesc" in kd.h, but as it is a uapi header, I am not touching > these. > > Signed-off-by: Jiri Slaby <jslaby@suse.cz> > Link: https://lore.kernel.org/r/20210105120239.28031-8-jslaby@suse.cz > Cc: guodaxing <guodaxing@huawei.com> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > CVE-2021-33656 > (cherry picked from commit c87e851b23e5cb2ba90a3049ef38340ed7d5746f linux-5.4.y) > Signed-off-by: Cengiz Can <cengiz.can@canonical.com> > --- Applied to focal:linux/master-next. Thanks. -Stefan > drivers/tty/vt/vt.c | 39 +--------- > drivers/tty/vt/vt_ioctl.c | 147 -------------------------------------- > include/linux/kd.h | 8 --- > 3 files changed, 3 insertions(+), 191 deletions(-) > delete mode 100644 include/linux/kd.h > > diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c > index da2344e5ec340..c28e976a835d6 100644 > --- a/drivers/tty/vt/vt.c > +++ b/drivers/tty/vt/vt.c > @@ -4568,16 +4568,8 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op) > > if (op->data && font.charcount > op->charcount) > rc = -ENOSPC; > - if (!(op->flags & KD_FONT_FLAG_OLD)) { > - if (font.width > op->width || font.height > op->height) > - rc = -ENOSPC; > - } else { > - if (font.width != 8) > - rc = -EIO; > - else if ((op->height && font.height > op->height) || > - font.height > 32) > - rc = -ENOSPC; > - } > + if (font.width > op->width || font.height > op->height) > + rc = -ENOSPC; > if (rc) > goto out; > > @@ -4605,7 +4597,7 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op) > return -EINVAL; > if (op->charcount > 512) > return -EINVAL; > - if (op->width <= 0 || op->width > 32 || op->height > 32) > + if (op->width <= 0 || op->width > 32 || !op->height || op->height > 32) > return -EINVAL; > size = (op->width+7)/8 * 32 * op->charcount; > if (size > max_font_size) > @@ -4615,31 +4607,6 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op) > if (IS_ERR(font.data)) > return PTR_ERR(font.data); > > - if (!op->height) { /* Need to guess font height [compat] */ > - int h, i; > - u8 *charmap = font.data; > - > - /* > - * If from KDFONTOP ioctl, don't allow things which can be done > - * in userland,so that we can get rid of this soon > - */ > - if (!(op->flags & KD_FONT_FLAG_OLD)) { > - kfree(font.data); > - return -EINVAL; > - } > - > - for (h = 32; h > 0; h--) > - for (i = 0; i < op->charcount; i++) > - if (charmap[32*i+h-1]) > - goto nonzero; > - > - kfree(font.data); > - return -EINVAL; > - > - nonzero: > - op->height = h; > - } > - > font.charcount = op->charcount; > font.width = op->width; > font.height = op->height; > diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c > index 9db03dc7eeb99..38cc69477eecc 100644 > --- a/drivers/tty/vt/vt_ioctl.c > +++ b/drivers/tty/vt/vt_ioctl.c > @@ -241,48 +241,6 @@ int vt_waitactive(int n) > #define GPLAST 0x3df > #define GPNUM (GPLAST - GPFIRST + 1) > > - > - > -static inline int > -do_fontx_ioctl(struct vc_data *vc, int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op) > -{ > - struct consolefontdesc cfdarg; > - int i; > - > - if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc))) > - return -EFAULT; > - > - switch (cmd) { > - case PIO_FONTX: > - if (!perm) > - return -EPERM; > - op->op = KD_FONT_OP_SET; > - op->flags = KD_FONT_FLAG_OLD; > - op->width = 8; > - op->height = cfdarg.charheight; > - op->charcount = cfdarg.charcount; > - op->data = cfdarg.chardata; > - return con_font_op(vc, op); > - > - case GIO_FONTX: > - op->op = KD_FONT_OP_GET; > - op->flags = KD_FONT_FLAG_OLD; > - op->width = 8; > - op->height = cfdarg.charheight; > - op->charcount = cfdarg.charcount; > - op->data = cfdarg.chardata; > - i = con_font_op(vc, op); > - if (i) > - return i; > - cfdarg.charheight = op->height; > - cfdarg.charcount = op->charcount; > - if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc))) > - return -EFAULT; > - return 0; > - } > - return -EINVAL; > -} > - > static inline int > do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_data *vc) > { > @@ -919,30 +877,6 @@ int vt_ioctl(struct tty_struct *tty, > break; > } > > - case PIO_FONT: { > - if (!perm) > - return -EPERM; > - op.op = KD_FONT_OP_SET; > - op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */ > - op.width = 8; > - op.height = 0; > - op.charcount = 256; > - op.data = up; > - ret = con_font_op(vc, &op); > - break; > - } > - > - case GIO_FONT: { > - op.op = KD_FONT_OP_GET; > - op.flags = KD_FONT_FLAG_OLD; > - op.width = 8; > - op.height = 32; > - op.charcount = 256; > - op.data = up; > - ret = con_font_op(vc, &op); > - break; > - } > - > case PIO_CMAP: > if (!perm) > ret = -EPERM; > @@ -954,36 +888,6 @@ int vt_ioctl(struct tty_struct *tty, > ret = con_get_cmap(up); > break; > > - case PIO_FONTX: > - case GIO_FONTX: > - ret = do_fontx_ioctl(vc, cmd, up, perm, &op); > - break; > - > - case PIO_FONTRESET: > - { > - if (!perm) > - return -EPERM; > - > -#ifdef BROKEN_GRAPHICS_PROGRAMS > - /* With BROKEN_GRAPHICS_PROGRAMS defined, the default > - font is not saved. */ > - ret = -ENOSYS; > - break; > -#else > - { > - op.op = KD_FONT_OP_SET_DEFAULT; > - op.data = NULL; > - ret = con_font_op(vc, &op); > - if (ret) > - break; > - console_lock(); > - con_set_default_unimap(vc); > - console_unlock(); > - break; > - } > -#endif > - } > - > case KDFONTOP: { > if (copy_from_user(&op, up, sizeof(op))) { > ret = -EFAULT; > @@ -1097,54 +1001,6 @@ void vc_SAK(struct work_struct *work) > > #ifdef CONFIG_COMPAT > > -struct compat_consolefontdesc { > - unsigned short charcount; /* characters in font (256 or 512) */ > - unsigned short charheight; /* scan lines per character (1-32) */ > - compat_caddr_t chardata; /* font data in expanded form */ > -}; > - > -static inline int > -compat_fontx_ioctl(struct vc_data *vc, int cmd, > - struct compat_consolefontdesc __user *user_cfd, > - int perm, struct console_font_op *op) > -{ > - struct compat_consolefontdesc cfdarg; > - int i; > - > - if (copy_from_user(&cfdarg, user_cfd, sizeof(struct compat_consolefontdesc))) > - return -EFAULT; > - > - switch (cmd) { > - case PIO_FONTX: > - if (!perm) > - return -EPERM; > - op->op = KD_FONT_OP_SET; > - op->flags = KD_FONT_FLAG_OLD; > - op->width = 8; > - op->height = cfdarg.charheight; > - op->charcount = cfdarg.charcount; > - op->data = compat_ptr(cfdarg.chardata); > - return con_font_op(vc, op); > - > - case GIO_FONTX: > - op->op = KD_FONT_OP_GET; > - op->flags = KD_FONT_FLAG_OLD; > - op->width = 8; > - op->height = cfdarg.charheight; > - op->charcount = cfdarg.charcount; > - op->data = compat_ptr(cfdarg.chardata); > - i = con_font_op(vc, op); > - if (i) > - return i; > - cfdarg.charheight = op->height; > - cfdarg.charcount = op->charcount; > - if (copy_to_user(user_cfd, &cfdarg, sizeof(struct compat_consolefontdesc))) > - return -EFAULT; > - return 0; > - } > - return -EINVAL; > -} > - > struct compat_console_font_op { > compat_uint_t op; /* operation code KD_FONT_OP_* */ > compat_uint_t flags; /* KD_FONT_FLAG_* */ > @@ -1221,9 +1077,6 @@ long vt_compat_ioctl(struct tty_struct *tty, > /* > * these need special handlers for incompatible data structures > */ > - case PIO_FONTX: > - case GIO_FONTX: > - return compat_fontx_ioctl(vc, cmd, up, perm, &op); > > case KDFONTOP: > return compat_kdfontop_ioctl(up, perm, &op, vc); > diff --git a/include/linux/kd.h b/include/linux/kd.h > deleted file mode 100644 > index b130a18f860f0..0000000000000 > --- a/include/linux/kd.h > +++ /dev/null > @@ -1,8 +0,0 @@ > -/* SPDX-License-Identifier: GPL-2.0 */ > -#ifndef _LINUX_KD_H > -#define _LINUX_KD_H > - > -#include <uapi/linux/kd.h> > - > -#define KD_FONT_FLAG_OLD 0x80000000 /* Invoked via old interface [compat] */ > -#endif /* _LINUX_KD_H */
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index da2344e5ec340..c28e976a835d6 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -4568,16 +4568,8 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op) if (op->data && font.charcount > op->charcount) rc = -ENOSPC; - if (!(op->flags & KD_FONT_FLAG_OLD)) { - if (font.width > op->width || font.height > op->height) - rc = -ENOSPC; - } else { - if (font.width != 8) - rc = -EIO; - else if ((op->height && font.height > op->height) || - font.height > 32) - rc = -ENOSPC; - } + if (font.width > op->width || font.height > op->height) + rc = -ENOSPC; if (rc) goto out; @@ -4605,7 +4597,7 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op) return -EINVAL; if (op->charcount > 512) return -EINVAL; - if (op->width <= 0 || op->width > 32 || op->height > 32) + if (op->width <= 0 || op->width > 32 || !op->height || op->height > 32) return -EINVAL; size = (op->width+7)/8 * 32 * op->charcount; if (size > max_font_size) @@ -4615,31 +4607,6 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op) if (IS_ERR(font.data)) return PTR_ERR(font.data); - if (!op->height) { /* Need to guess font height [compat] */ - int h, i; - u8 *charmap = font.data; - - /* - * If from KDFONTOP ioctl, don't allow things which can be done - * in userland,so that we can get rid of this soon - */ - if (!(op->flags & KD_FONT_FLAG_OLD)) { - kfree(font.data); - return -EINVAL; - } - - for (h = 32; h > 0; h--) - for (i = 0; i < op->charcount; i++) - if (charmap[32*i+h-1]) - goto nonzero; - - kfree(font.data); - return -EINVAL; - - nonzero: - op->height = h; - } - font.charcount = op->charcount; font.width = op->width; font.height = op->height; diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 9db03dc7eeb99..38cc69477eecc 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -241,48 +241,6 @@ int vt_waitactive(int n) #define GPLAST 0x3df #define GPNUM (GPLAST - GPFIRST + 1) - - -static inline int -do_fontx_ioctl(struct vc_data *vc, int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op) -{ - struct consolefontdesc cfdarg; - int i; - - if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc))) - return -EFAULT; - - switch (cmd) { - case PIO_FONTX: - if (!perm) - return -EPERM; - op->op = KD_FONT_OP_SET; - op->flags = KD_FONT_FLAG_OLD; - op->width = 8; - op->height = cfdarg.charheight; - op->charcount = cfdarg.charcount; - op->data = cfdarg.chardata; - return con_font_op(vc, op); - - case GIO_FONTX: - op->op = KD_FONT_OP_GET; - op->flags = KD_FONT_FLAG_OLD; - op->width = 8; - op->height = cfdarg.charheight; - op->charcount = cfdarg.charcount; - op->data = cfdarg.chardata; - i = con_font_op(vc, op); - if (i) - return i; - cfdarg.charheight = op->height; - cfdarg.charcount = op->charcount; - if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc))) - return -EFAULT; - return 0; - } - return -EINVAL; -} - static inline int do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_data *vc) { @@ -919,30 +877,6 @@ int vt_ioctl(struct tty_struct *tty, break; } - case PIO_FONT: { - if (!perm) - return -EPERM; - op.op = KD_FONT_OP_SET; - op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */ - op.width = 8; - op.height = 0; - op.charcount = 256; - op.data = up; - ret = con_font_op(vc, &op); - break; - } - - case GIO_FONT: { - op.op = KD_FONT_OP_GET; - op.flags = KD_FONT_FLAG_OLD; - op.width = 8; - op.height = 32; - op.charcount = 256; - op.data = up; - ret = con_font_op(vc, &op); - break; - } - case PIO_CMAP: if (!perm) ret = -EPERM; @@ -954,36 +888,6 @@ int vt_ioctl(struct tty_struct *tty, ret = con_get_cmap(up); break; - case PIO_FONTX: - case GIO_FONTX: - ret = do_fontx_ioctl(vc, cmd, up, perm, &op); - break; - - case PIO_FONTRESET: - { - if (!perm) - return -EPERM; - -#ifdef BROKEN_GRAPHICS_PROGRAMS - /* With BROKEN_GRAPHICS_PROGRAMS defined, the default - font is not saved. */ - ret = -ENOSYS; - break; -#else - { - op.op = KD_FONT_OP_SET_DEFAULT; - op.data = NULL; - ret = con_font_op(vc, &op); - if (ret) - break; - console_lock(); - con_set_default_unimap(vc); - console_unlock(); - break; - } -#endif - } - case KDFONTOP: { if (copy_from_user(&op, up, sizeof(op))) { ret = -EFAULT; @@ -1097,54 +1001,6 @@ void vc_SAK(struct work_struct *work) #ifdef CONFIG_COMPAT -struct compat_consolefontdesc { - unsigned short charcount; /* characters in font (256 or 512) */ - unsigned short charheight; /* scan lines per character (1-32) */ - compat_caddr_t chardata; /* font data in expanded form */ -}; - -static inline int -compat_fontx_ioctl(struct vc_data *vc, int cmd, - struct compat_consolefontdesc __user *user_cfd, - int perm, struct console_font_op *op) -{ - struct compat_consolefontdesc cfdarg; - int i; - - if (copy_from_user(&cfdarg, user_cfd, sizeof(struct compat_consolefontdesc))) - return -EFAULT; - - switch (cmd) { - case PIO_FONTX: - if (!perm) - return -EPERM; - op->op = KD_FONT_OP_SET; - op->flags = KD_FONT_FLAG_OLD; - op->width = 8; - op->height = cfdarg.charheight; - op->charcount = cfdarg.charcount; - op->data = compat_ptr(cfdarg.chardata); - return con_font_op(vc, op); - - case GIO_FONTX: - op->op = KD_FONT_OP_GET; - op->flags = KD_FONT_FLAG_OLD; - op->width = 8; - op->height = cfdarg.charheight; - op->charcount = cfdarg.charcount; - op->data = compat_ptr(cfdarg.chardata); - i = con_font_op(vc, op); - if (i) - return i; - cfdarg.charheight = op->height; - cfdarg.charcount = op->charcount; - if (copy_to_user(user_cfd, &cfdarg, sizeof(struct compat_consolefontdesc))) - return -EFAULT; - return 0; - } - return -EINVAL; -} - struct compat_console_font_op { compat_uint_t op; /* operation code KD_FONT_OP_* */ compat_uint_t flags; /* KD_FONT_FLAG_* */ @@ -1221,9 +1077,6 @@ long vt_compat_ioctl(struct tty_struct *tty, /* * these need special handlers for incompatible data structures */ - case PIO_FONTX: - case GIO_FONTX: - return compat_fontx_ioctl(vc, cmd, up, perm, &op); case KDFONTOP: return compat_kdfontop_ioctl(up, perm, &op, vc); diff --git a/include/linux/kd.h b/include/linux/kd.h deleted file mode 100644 index b130a18f860f0..0000000000000 --- a/include/linux/kd.h +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _LINUX_KD_H -#define _LINUX_KD_H - -#include <uapi/linux/kd.h> - -#define KD_FONT_FLAG_OLD 0x80000000 /* Invoked via old interface [compat] */ -#endif /* _LINUX_KD_H */