diff options
Diffstat (limited to 'drivers/tty/vt')
-rw-r--r-- | drivers/tty/vt/consolemap.c | 1 | ||||
-rw-r--r-- | drivers/tty/vt/keyboard.c | 1 | ||||
-rw-r--r-- | drivers/tty/vt/vt.c | 107 |
3 files changed, 59 insertions, 50 deletions
diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index a5f88cf0f61d..722a6690c70d 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c | |||
@@ -1,3 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * consolemap.c | 3 | * consolemap.c |
3 | * | 4 | * |
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index f974d6340d04..c8d90d7e7e37 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c | |||
@@ -1,3 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * Written for linux by Johan Myreen as a translation from | 3 | * Written for linux by Johan Myreen as a translation from |
3 | * the assembly version by Linus (with diacriticals added) | 4 | * the assembly version by Linus (with diacriticals added) |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 602d71630952..bce4c71cb338 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -1,3 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * Copyright (C) 1991, 1992 Linus Torvalds | 3 | * Copyright (C) 1991, 1992 Linus Torvalds |
3 | */ | 4 | */ |
@@ -102,6 +103,7 @@ | |||
102 | #include <linux/uaccess.h> | 103 | #include <linux/uaccess.h> |
103 | #include <linux/kdb.h> | 104 | #include <linux/kdb.h> |
104 | #include <linux/ctype.h> | 105 | #include <linux/ctype.h> |
106 | #include <linux/bsearch.h> | ||
105 | 107 | ||
106 | #define MAX_NR_CON_DRIVER 16 | 108 | #define MAX_NR_CON_DRIVER 16 |
107 | 109 | ||
@@ -2142,22 +2144,15 @@ struct interval { | |||
2142 | uint32_t last; | 2144 | uint32_t last; |
2143 | }; | 2145 | }; |
2144 | 2146 | ||
2145 | static int bisearch(uint32_t ucs, const struct interval *table, int max) | 2147 | static int ucs_cmp(const void *key, const void *elt) |
2146 | { | 2148 | { |
2147 | int min = 0; | 2149 | uint32_t ucs = *(uint32_t *)key; |
2148 | int mid; | 2150 | struct interval e = *(struct interval *) elt; |
2149 | 2151 | ||
2150 | if (ucs < table[0].first || ucs > table[max].last) | 2152 | if (ucs > e.last) |
2151 | return 0; | 2153 | return 1; |
2152 | while (max >= min) { | 2154 | else if (ucs < e.first) |
2153 | mid = (min + max) / 2; | 2155 | return -1; |
2154 | if (ucs > table[mid].last) | ||
2155 | min = mid + 1; | ||
2156 | else if (ucs < table[mid].first) | ||
2157 | max = mid - 1; | ||
2158 | else | ||
2159 | return 1; | ||
2160 | } | ||
2161 | return 0; | 2156 | return 0; |
2162 | } | 2157 | } |
2163 | 2158 | ||
@@ -2169,7 +2164,12 @@ static int is_double_width(uint32_t ucs) | |||
2169 | { 0xFE10, 0xFE19 }, { 0xFE30, 0xFE6F }, { 0xFF00, 0xFF60 }, | 2164 | { 0xFE10, 0xFE19 }, { 0xFE30, 0xFE6F }, { 0xFF00, 0xFF60 }, |
2170 | { 0xFFE0, 0xFFE6 }, { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD } | 2165 | { 0xFFE0, 0xFFE6 }, { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD } |
2171 | }; | 2166 | }; |
2172 | return bisearch(ucs, double_width, ARRAY_SIZE(double_width) - 1); | 2167 | if (ucs < double_width[0].first || |
2168 | ucs > double_width[ARRAY_SIZE(double_width) - 1].last) | ||
2169 | return 0; | ||
2170 | |||
2171 | return bsearch(&ucs, double_width, ARRAY_SIZE(double_width), | ||
2172 | sizeof(struct interval), ucs_cmp) != NULL; | ||
2173 | } | 2173 | } |
2174 | 2174 | ||
2175 | static void con_flush(struct vc_data *vc, unsigned long draw_from, | 2175 | static void con_flush(struct vc_data *vc, unsigned long draw_from, |
@@ -2205,7 +2205,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co | |||
2205 | console_lock(); | 2205 | console_lock(); |
2206 | vc = tty->driver_data; | 2206 | vc = tty->driver_data; |
2207 | if (vc == NULL) { | 2207 | if (vc == NULL) { |
2208 | printk(KERN_ERR "vt: argh, driver_data is NULL !\n"); | 2208 | pr_err("vt: argh, driver_data is NULL !\n"); |
2209 | console_unlock(); | 2209 | console_unlock(); |
2210 | return 0; | 2210 | return 0; |
2211 | } | 2211 | } |
@@ -3190,20 +3190,21 @@ static int do_bind_con_driver(const struct consw *csw, int first, int last, | |||
3190 | 3190 | ||
3191 | pr_info("Console: switching "); | 3191 | pr_info("Console: switching "); |
3192 | if (!deflt) | 3192 | if (!deflt) |
3193 | printk(KERN_CONT "consoles %d-%d ", first+1, last+1); | 3193 | pr_cont("consoles %d-%d ", first + 1, last + 1); |
3194 | if (j >= 0) { | 3194 | if (j >= 0) { |
3195 | struct vc_data *vc = vc_cons[j].d; | 3195 | struct vc_data *vc = vc_cons[j].d; |
3196 | 3196 | ||
3197 | printk(KERN_CONT "to %s %s %dx%d\n", | 3197 | pr_cont("to %s %s %dx%d\n", |
3198 | vc->vc_can_do_color ? "colour" : "mono", | 3198 | vc->vc_can_do_color ? "colour" : "mono", |
3199 | desc, vc->vc_cols, vc->vc_rows); | 3199 | desc, vc->vc_cols, vc->vc_rows); |
3200 | 3200 | ||
3201 | if (k >= 0) { | 3201 | if (k >= 0) { |
3202 | vc = vc_cons[k].d; | 3202 | vc = vc_cons[k].d; |
3203 | update_screen(vc); | 3203 | update_screen(vc); |
3204 | } | 3204 | } |
3205 | } else | 3205 | } else { |
3206 | printk(KERN_CONT "to %s\n", desc); | 3206 | pr_cont("to %s\n", desc); |
3207 | } | ||
3207 | 3208 | ||
3208 | retval = 0; | 3209 | retval = 0; |
3209 | err: | 3210 | err: |
@@ -3622,9 +3623,8 @@ static int do_register_con_driver(const struct consw *csw, int first, int last) | |||
3622 | con_driver, con_dev_groups, | 3623 | con_driver, con_dev_groups, |
3623 | "vtcon%i", con_driver->node); | 3624 | "vtcon%i", con_driver->node); |
3624 | if (IS_ERR(con_driver->dev)) { | 3625 | if (IS_ERR(con_driver->dev)) { |
3625 | printk(KERN_WARNING "Unable to create device for %s; " | 3626 | pr_warn("Unable to create device for %s; errno = %ld\n", |
3626 | "errno = %ld\n", con_driver->desc, | 3627 | con_driver->desc, PTR_ERR(con_driver->dev)); |
3627 | PTR_ERR(con_driver->dev)); | ||
3628 | con_driver->dev = NULL; | 3628 | con_driver->dev = NULL; |
3629 | } else { | 3629 | } else { |
3630 | vtconsole_init_device(con_driver); | 3630 | vtconsole_init_device(con_driver); |
@@ -3761,8 +3761,8 @@ static int __init vtconsole_class_init(void) | |||
3761 | 3761 | ||
3762 | vtconsole_class = class_create(THIS_MODULE, "vtconsole"); | 3762 | vtconsole_class = class_create(THIS_MODULE, "vtconsole"); |
3763 | if (IS_ERR(vtconsole_class)) { | 3763 | if (IS_ERR(vtconsole_class)) { |
3764 | printk(KERN_WARNING "Unable to create vt console class; " | 3764 | pr_warn("Unable to create vt console class; errno = %ld\n", |
3765 | "errno = %ld\n", PTR_ERR(vtconsole_class)); | 3765 | PTR_ERR(vtconsole_class)); |
3766 | vtconsole_class = NULL; | 3766 | vtconsole_class = NULL; |
3767 | } | 3767 | } |
3768 | 3768 | ||
@@ -3778,9 +3778,8 @@ static int __init vtconsole_class_init(void) | |||
3778 | "vtcon%i", con->node); | 3778 | "vtcon%i", con->node); |
3779 | 3779 | ||
3780 | if (IS_ERR(con->dev)) { | 3780 | if (IS_ERR(con->dev)) { |
3781 | printk(KERN_WARNING "Unable to create " | 3781 | pr_warn("Unable to create device for %s; errno = %ld\n", |
3782 | "device for %s; errno = %ld\n", | 3782 | con->desc, PTR_ERR(con->dev)); |
3783 | con->desc, PTR_ERR(con->dev)); | ||
3784 | con->dev = NULL; | 3783 | con->dev = NULL; |
3785 | } else { | 3784 | } else { |
3786 | vtconsole_init_device(con); | 3785 | vtconsole_init_device(con); |
@@ -4121,37 +4120,45 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op) | |||
4121 | return -EINVAL; | 4120 | return -EINVAL; |
4122 | if (op->charcount > 512) | 4121 | if (op->charcount > 512) |
4123 | return -EINVAL; | 4122 | return -EINVAL; |
4123 | if (op->width <= 0 || op->width > 32 || op->height > 32) | ||
4124 | return -EINVAL; | ||
4125 | size = (op->width+7)/8 * 32 * op->charcount; | ||
4126 | if (size > max_font_size) | ||
4127 | return -ENOSPC; | ||
4128 | |||
4129 | font.data = memdup_user(op->data, size); | ||
4130 | if (IS_ERR(font.data)) | ||
4131 | return PTR_ERR(font.data); | ||
4132 | |||
4124 | if (!op->height) { /* Need to guess font height [compat] */ | 4133 | if (!op->height) { /* Need to guess font height [compat] */ |
4125 | int h, i; | 4134 | int h, i; |
4126 | u8 __user *charmap = op->data; | 4135 | u8 *charmap = font.data; |
4127 | u8 tmp; | 4136 | |
4128 | 4137 | /* | |
4129 | /* If from KDFONTOP ioctl, don't allow things which can be done in userland, | 4138 | * If from KDFONTOP ioctl, don't allow things which can be done |
4130 | so that we can get rid of this soon */ | 4139 | * in userland,so that we can get rid of this soon |
4131 | if (!(op->flags & KD_FONT_FLAG_OLD)) | 4140 | */ |
4141 | if (!(op->flags & KD_FONT_FLAG_OLD)) { | ||
4142 | kfree(font.data); | ||
4132 | return -EINVAL; | 4143 | return -EINVAL; |
4144 | } | ||
4145 | |||
4133 | for (h = 32; h > 0; h--) | 4146 | for (h = 32; h > 0; h--) |
4134 | for (i = 0; i < op->charcount; i++) { | 4147 | for (i = 0; i < op->charcount; i++) |
4135 | if (get_user(tmp, &charmap[32*i+h-1])) | 4148 | if (charmap[32*i+h-1]) |
4136 | return -EFAULT; | ||
4137 | if (tmp) | ||
4138 | goto nonzero; | 4149 | goto nonzero; |
4139 | } | 4150 | |
4151 | kfree(font.data); | ||
4140 | return -EINVAL; | 4152 | return -EINVAL; |
4153 | |||
4141 | nonzero: | 4154 | nonzero: |
4142 | op->height = h; | 4155 | op->height = h; |
4143 | } | 4156 | } |
4144 | if (op->width <= 0 || op->width > 32 || op->height > 32) | 4157 | |
4145 | return -EINVAL; | ||
4146 | size = (op->width+7)/8 * 32 * op->charcount; | ||
4147 | if (size > max_font_size) | ||
4148 | return -ENOSPC; | ||
4149 | font.charcount = op->charcount; | 4158 | font.charcount = op->charcount; |
4150 | font.height = op->height; | ||
4151 | font.width = op->width; | 4159 | font.width = op->width; |
4152 | font.data = memdup_user(op->data, size); | 4160 | font.height = op->height; |
4153 | if (IS_ERR(font.data)) | 4161 | |
4154 | return PTR_ERR(font.data); | ||
4155 | console_lock(); | 4162 | console_lock(); |
4156 | if (vc->vc_mode != KD_TEXT) | 4163 | if (vc->vc_mode != KD_TEXT) |
4157 | rc = -EINVAL; | 4164 | rc = -EINVAL; |