Commit 728702c6 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] con_get_font sanitized

->con_font_get() sanitized.  We pass console_font * to method instead of
console_font_op * and do not mess with mixing ->data in these guys.
Signed-off-by: default avatarAl Viro <viro@parcelfarce.linux.org.uk>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f5f697ab
...@@ -3026,56 +3026,52 @@ void reset_palette(int currcons) ...@@ -3026,56 +3026,52 @@ void reset_palette(int currcons)
int con_font_get(int currcons, struct console_font_op *op) int con_font_get(int currcons, struct console_font_op *op)
{ {
struct console_font_op old_op; struct console_font font;
int rc = -EINVAL; int rc = -EINVAL;
u8 *temp = NULL;
int c; int c;
if (vt_cons[currcons]->vc_mode != KD_TEXT) if (vt_cons[currcons]->vc_mode != KD_TEXT)
return -EINVAL; return -EINVAL;
memcpy(&old_op, op, sizeof(old_op));
if (op->data) { if (op->data) {
temp = kmalloc(max_font_size, GFP_KERNEL); font.data = kmalloc(max_font_size, GFP_KERNEL);
if (!temp) if (!font.data)
return -ENOMEM; return -ENOMEM;
op->data = temp; } else
} font.data = NULL;
acquire_console_sem(); acquire_console_sem();
if (sw->con_font_get) if (sw->con_font_get)
rc = sw->con_font_get(vc_cons[currcons].d, op); rc = sw->con_font_get(vc_cons[currcons].d, &font);
else else
rc = -ENOSYS; rc = -ENOSYS;
release_console_sem(); release_console_sem();
op->data = old_op.data;
if (rc) if (rc)
goto out; goto out;
c = (op->width+7)/8 * 32 * op->charcount; c = (font.width+7)/8 * 32 * font.charcount;
if (op->data && op->charcount > old_op.charcount) if (op->data && font.charcount > op->charcount)
rc = -ENOSPC; rc = -ENOSPC;
if (!(op->flags & KD_FONT_FLAG_OLD)) { if (!(op->flags & KD_FONT_FLAG_OLD)) {
if (op->width > old_op.width || if (font.width > op->width || font.height > op->height)
op->height > old_op.height)
rc = -ENOSPC; rc = -ENOSPC;
} else { } else {
if (op->width != 8) if (font.width != 8)
rc = -EIO; rc = -EIO;
else if ((old_op.height && op->height > old_op.height) || else if ((op->height && font.height > op->height) ||
op->height > 32) font.height > 32)
rc = -ENOSPC; rc = -ENOSPC;
} }
if (rc) if (rc)
goto out; goto out;
if (op->data && copy_to_user(op->data, temp, c)) if (op->data && copy_to_user(op->data, font.data, c))
rc = -EFAULT; rc = -EFAULT;
out: out:
kfree(temp); kfree(font.data);
return rc; return rc;
} }
......
...@@ -2000,36 +2000,36 @@ static void fbcon_free_font(struct display *p) ...@@ -2000,36 +2000,36 @@ static void fbcon_free_font(struct display *p)
p->userfont = 0; p->userfont = 0;
} }
static int fbcon_get_font(struct vc_data *vc, struct console_font_op *op) static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
{ {
u8 *fontdata = vc->vc_font.data; u8 *fontdata = vc->vc_font.data;
u8 *data = op->data; u8 *data = font->data;
int i, j; int i, j;
op->width = vc->vc_font.width; font->width = vc->vc_font.width;
op->height = vc->vc_font.height; font->height = vc->vc_font.height;
op->charcount = vc->vc_hi_font_mask ? 512 : 256; font->charcount = vc->vc_hi_font_mask ? 512 : 256;
if (!op->data) if (!font->data)
return 0; return 0;
if (op->width <= 8) { if (font->width <= 8) {
j = vc->vc_font.height; j = vc->vc_font.height;
for (i = 0; i < op->charcount; i++) { for (i = 0; i < font->charcount; i++) {
memcpy(data, fontdata, j); memcpy(data, fontdata, j);
memset(data + j, 0, 32 - j); memset(data + j, 0, 32 - j);
data += 32; data += 32;
fontdata += j; fontdata += j;
} }
} else if (op->width <= 16) { } else if (font->width <= 16) {
j = vc->vc_font.height * 2; j = vc->vc_font.height * 2;
for (i = 0; i < op->charcount; i++) { for (i = 0; i < font->charcount; i++) {
memcpy(data, fontdata, j); memcpy(data, fontdata, j);
memset(data + j, 0, 64 - j); memset(data + j, 0, 64 - j);
data += 64; data += 64;
fontdata += j; fontdata += j;
} }
} else if (op->width <= 24) { } else if (font->width <= 24) {
for (i = 0; i < op->charcount; i++) { for (i = 0; i < font->charcount; i++) {
for (j = 0; j < vc->vc_font.height; j++) { for (j = 0; j < vc->vc_font.height; j++) {
*data++ = fontdata[0]; *data++ = fontdata[0];
*data++ = fontdata[1]; *data++ = fontdata[1];
...@@ -2041,7 +2041,7 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font_op *op) ...@@ -2041,7 +2041,7 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font_op *op)
} }
} else { } else {
j = vc->vc_font.height * 4; j = vc->vc_font.height * 4;
for (i = 0; i < op->charcount; i++) { for (i = 0; i < font->charcount; i++) {
memcpy(data, fontdata, j); memcpy(data, fontdata, j);
memset(data + j, 0, 128 - j); memset(data + j, 0, 128 - j);
data += 128; data += 128;
......
...@@ -927,17 +927,17 @@ static int vgacon_font_set(struct vc_data *c, struct console_font *font, unsigne ...@@ -927,17 +927,17 @@ static int vgacon_font_set(struct vc_data *c, struct console_font *font, unsigne
return rc; return rc;
} }
static int vgacon_font_get(struct vc_data *c, struct console_font_op *op) static int vgacon_font_get(struct vc_data *c, struct console_font *font)
{ {
if (vga_video_type < VIDEO_TYPE_EGAM) if (vga_video_type < VIDEO_TYPE_EGAM)
return -EINVAL; return -EINVAL;
op->width = 8; font->width = 8;
op->height = c->vc_font.height; font->height = c->vc_font.height;
op->charcount = vga_512_chars ? 512 : 256; font->charcount = vga_512_chars ? 512 : 256;
if (!op->data) if (!font->data)
return 0; return 0;
return vgacon_do_font_op(&state, op->data, 0, 0); return vgacon_do_font_op(&state, font->data, 0, 0);
} }
#else #else
......
...@@ -42,7 +42,7 @@ struct consw { ...@@ -42,7 +42,7 @@ struct consw {
int (*con_switch)(struct vc_data *); int (*con_switch)(struct vc_data *);
int (*con_blank)(struct vc_data *, int, int); int (*con_blank)(struct vc_data *, int, int);
int (*con_font_set)(struct vc_data *, struct console_font *, unsigned); int (*con_font_set)(struct vc_data *, struct console_font *, unsigned);
int (*con_font_get)(struct vc_data *, struct console_font_op *); int (*con_font_get)(struct vc_data *, struct console_font *);
int (*con_font_default)(struct vc_data *, struct console_font *, char *); int (*con_font_default)(struct vc_data *, struct console_font *, char *);
int (*con_font_copy)(struct vc_data *, int); int (*con_font_copy)(struct vc_data *, int);
int (*con_resize)(struct vc_data *, unsigned int, unsigned int); int (*con_resize)(struct vc_data *, unsigned int, unsigned int);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment