summaryrefslogtreecommitdiffstats
path: root/drivers/tty/vt/vt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/vt/vt.c')
-rw-r--r--drivers/tty/vt/vt.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 5e41fac5816f..e50492357202 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -4119,37 +4119,45 @@ 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)
+ return -EINVAL;
+ size = (op->width+7)/8 * 32 * op->charcount;
+ if (size > max_font_size)
+ return -ENOSPC;
+
+ font.data = memdup_user(op->data, size);
+ if (IS_ERR(font.data))
+ return PTR_ERR(font.data);
+
if (!op->height) { /* Need to guess font height [compat] */
int h, i;
- u8 __user *charmap = op->data;
- u8 tmp;
-
- /* 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))
+ 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 (get_user(tmp, &charmap[32*i+h-1]))
- return -EFAULT;
- if (tmp)
+ for (i = 0; i < op->charcount; i++)
+ if (charmap[32*i+h-1])
goto nonzero;
- }
+
+ kfree(font.data);
return -EINVAL;
+
nonzero:
op->height = h;
}
- if (op->width <= 0 || op->width > 32 || op->height > 32)
- return -EINVAL;
- size = (op->width+7)/8 * 32 * op->charcount;
- if (size > max_font_size)
- return -ENOSPC;
+
font.charcount = op->charcount;
- font.height = op->height;
font.width = op->width;
- font.data = memdup_user(op->data, size);
- if (IS_ERR(font.data))
- return PTR_ERR(font.data);
+ font.height = op->height;
+
console_lock();
if (vc->vc_mode != KD_TEXT)
rc = -EINVAL;