Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

vt: drop old FONT ioctls

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
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Jiri Slaby and committed by
Greg Kroah-Hartman
ff2047fb 9777f8e6

+3 -195
+3 -36
drivers/tty/vt/vt.c
··· 4583 4583 4584 4584 if (op->data && font.charcount > op->charcount) 4585 4585 rc = -ENOSPC; 4586 - if (!(op->flags & KD_FONT_FLAG_OLD)) { 4587 - if (font.width > op->width || font.height > op->height) 4588 - rc = -ENOSPC; 4589 - } else { 4590 - if (font.width != 8) 4591 - rc = -EIO; 4592 - else if ((op->height && font.height > op->height) || 4593 - font.height > 32) 4594 - rc = -ENOSPC; 4595 - } 4586 + if (font.width > op->width || font.height > op->height) 4587 + rc = -ENOSPC; 4596 4588 if (rc) 4597 4589 goto out; 4598 4590 ··· 4612 4620 return -EINVAL; 4613 4621 if (op->charcount > 512) 4614 4622 return -EINVAL; 4615 - if (op->width <= 0 || op->width > 32 || op->height > 32) 4623 + if (op->width <= 0 || op->width > 32 || !op->height || op->height > 32) 4616 4624 return -EINVAL; 4617 4625 size = (op->width+7)/8 * 32 * op->charcount; 4618 4626 if (size > max_font_size) ··· 4621 4629 font.data = memdup_user(op->data, size); 4622 4630 if (IS_ERR(font.data)) 4623 4631 return PTR_ERR(font.data); 4624 - 4625 - if (!op->height) { /* Need to guess font height [compat] */ 4626 - int h, i; 4627 - u8 *charmap = font.data; 4628 - 4629 - /* 4630 - * If from KDFONTOP ioctl, don't allow things which can be done 4631 - * in userland,so that we can get rid of this soon 4632 - */ 4633 - if (!(op->flags & KD_FONT_FLAG_OLD)) { 4634 - kfree(font.data); 4635 - return -EINVAL; 4636 - } 4637 - 4638 - for (h = 32; h > 0; h--) 4639 - for (i = 0; i < op->charcount; i++) 4640 - if (charmap[32*i+h-1]) 4641 - goto nonzero; 4642 - 4643 - kfree(font.data); 4644 - return -EINVAL; 4645 - 4646 - nonzero: 4647 - op->height = h; 4648 - } 4649 4632 4650 4633 font.charcount = op->charcount; 4651 4634 font.width = op->width;
-151
drivers/tty/vt/vt_ioctl.c
··· 484 484 return 0; 485 485 } 486 486 487 - static inline int do_fontx_ioctl(struct vc_data *vc, int cmd, 488 - struct consolefontdesc __user *user_cfd, 489 - struct console_font_op *op) 490 - { 491 - struct consolefontdesc cfdarg; 492 - int i; 493 - 494 - if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc))) 495 - return -EFAULT; 496 - 497 - switch (cmd) { 498 - case PIO_FONTX: 499 - op->op = KD_FONT_OP_SET; 500 - op->flags = KD_FONT_FLAG_OLD; 501 - op->width = 8; 502 - op->height = cfdarg.charheight; 503 - op->charcount = cfdarg.charcount; 504 - op->data = cfdarg.chardata; 505 - return con_font_op(vc, op); 506 - 507 - case GIO_FONTX: 508 - op->op = KD_FONT_OP_GET; 509 - op->flags = KD_FONT_FLAG_OLD; 510 - op->width = 8; 511 - op->height = cfdarg.charheight; 512 - op->charcount = cfdarg.charcount; 513 - op->data = cfdarg.chardata; 514 - i = con_font_op(vc, op); 515 - if (i) 516 - return i; 517 - cfdarg.charheight = op->height; 518 - cfdarg.charcount = op->charcount; 519 - if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc))) 520 - return -EFAULT; 521 - return 0; 522 - } 523 - return -EINVAL; 524 - } 525 - 526 - static int vt_io_fontreset(struct vc_data *vc, struct console_font_op *op) 527 - { 528 - int ret; 529 - 530 - if (__is_defined(BROKEN_GRAPHICS_PROGRAMS)) { 531 - /* 532 - * With BROKEN_GRAPHICS_PROGRAMS defined, the default font is 533 - * not saved. 534 - */ 535 - return -ENOSYS; 536 - } 537 - 538 - op->op = KD_FONT_OP_SET_DEFAULT; 539 - op->data = NULL; 540 - ret = con_font_op(vc, op); 541 - if (ret) 542 - return ret; 543 - 544 - console_lock(); 545 - con_set_default_unimap(vc); 546 - console_unlock(); 547 - 548 - return 0; 549 - } 550 - 551 487 static inline int do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, 552 488 bool perm, struct vc_data *vc) 553 489 { ··· 508 572 static int vt_io_ioctl(struct vc_data *vc, unsigned int cmd, void __user *up, 509 573 bool perm) 510 574 { 511 - struct console_font_op op; /* used in multiple places here */ 512 - 513 575 switch (cmd) { 514 - case PIO_FONT: 515 - if (!perm) 516 - return -EPERM; 517 - op.op = KD_FONT_OP_SET; 518 - op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */ 519 - op.width = 8; 520 - op.height = 0; 521 - op.charcount = 256; 522 - op.data = up; 523 - return con_font_op(vc, &op); 524 - 525 - case GIO_FONT: 526 - op.op = KD_FONT_OP_GET; 527 - op.flags = KD_FONT_FLAG_OLD; 528 - op.width = 8; 529 - op.height = 32; 530 - op.charcount = 256; 531 - op.data = up; 532 - return con_font_op(vc, &op); 533 - 534 576 case PIO_CMAP: 535 577 if (!perm) 536 578 return -EPERM; ··· 516 602 517 603 case GIO_CMAP: 518 604 return con_get_cmap(up); 519 - 520 - case PIO_FONTX: 521 - if (!perm) 522 - return -EPERM; 523 - 524 - fallthrough; 525 - case GIO_FONTX: 526 - return do_fontx_ioctl(vc, cmd, up, &op); 527 - 528 - case PIO_FONTRESET: 529 - if (!perm) 530 - return -EPERM; 531 - 532 - return vt_io_fontreset(vc, &op); 533 605 534 606 case PIO_SCRNMAP: 535 607 if (!perm) ··· 959 1059 960 1060 #ifdef CONFIG_COMPAT 961 1061 962 - struct compat_consolefontdesc { 963 - unsigned short charcount; /* characters in font (256 or 512) */ 964 - unsigned short charheight; /* scan lines per character (1-32) */ 965 - compat_caddr_t chardata; /* font data in expanded form */ 966 - }; 967 - 968 - static inline int 969 - compat_fontx_ioctl(struct vc_data *vc, int cmd, 970 - struct compat_consolefontdesc __user *user_cfd, 971 - int perm, struct console_font_op *op) 972 - { 973 - struct compat_consolefontdesc cfdarg; 974 - int i; 975 - 976 - if (copy_from_user(&cfdarg, user_cfd, sizeof(struct compat_consolefontdesc))) 977 - return -EFAULT; 978 - 979 - switch (cmd) { 980 - case PIO_FONTX: 981 - if (!perm) 982 - return -EPERM; 983 - op->op = KD_FONT_OP_SET; 984 - op->flags = KD_FONT_FLAG_OLD; 985 - op->width = 8; 986 - op->height = cfdarg.charheight; 987 - op->charcount = cfdarg.charcount; 988 - op->data = compat_ptr(cfdarg.chardata); 989 - return con_font_op(vc, op); 990 - 991 - case GIO_FONTX: 992 - op->op = KD_FONT_OP_GET; 993 - op->flags = KD_FONT_FLAG_OLD; 994 - op->width = 8; 995 - op->height = cfdarg.charheight; 996 - op->charcount = cfdarg.charcount; 997 - op->data = compat_ptr(cfdarg.chardata); 998 - i = con_font_op(vc, op); 999 - if (i) 1000 - return i; 1001 - cfdarg.charheight = op->height; 1002 - cfdarg.charcount = op->charcount; 1003 - if (copy_to_user(user_cfd, &cfdarg, sizeof(struct compat_consolefontdesc))) 1004 - return -EFAULT; 1005 - return 0; 1006 - } 1007 - return -EINVAL; 1008 - } 1009 - 1010 1062 struct compat_console_font_op { 1011 1063 compat_uint_t op; /* operation code KD_FONT_OP_* */ 1012 1064 compat_uint_t flags; /* KD_FONT_FLAG_* */ ··· 1035 1183 /* 1036 1184 * these need special handlers for incompatible data structures 1037 1185 */ 1038 - case PIO_FONTX: 1039 - case GIO_FONTX: 1040 - return compat_fontx_ioctl(vc, cmd, up, perm, &op); 1041 1186 1042 1187 case KDFONTOP: 1043 1188 return compat_kdfontop_ioctl(up, perm, &op, vc);
-8
include/linux/kd.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef _LINUX_KD_H 3 - #define _LINUX_KD_H 4 - 5 - #include <uapi/linux/kd.h> 6 - 7 - #define KD_FONT_FLAG_OLD 0x80000000 /* Invoked via old interface [compat] */ 8 - #endif /* _LINUX_KD_H */