Commit 414edcd3 authored by Antonino A. Daplas's avatar Antonino A. Daplas Committed by Linus Torvalds

[PATCH] vt: fix possible memory corruption in complement_pos

Based on a patch from Andr Pereira de Almeida <andre@cachola.com.br>

It might be possible for the saved pointer (*p) to become invalid in
between vc_resizes, so saving the screen offset instead of the screen
pointer is saner.

This bug is very hard to trigger though, but Andre probably did, if he's
submitting this patch.  Anyway, with Andre's patch, it's still possible for
the offsets to be still illegal, if the new screen size is smaller than the
old one.  So I've also added checks if the offsets are still within the
screenbuffer size.
Signed-off-by: default avatarAntonino Daplas <adaplas@pol.net>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent eed74dfc
...@@ -434,21 +434,25 @@ void invert_screen(struct vc_data *vc, int offset, int count, int viewed) ...@@ -434,21 +434,25 @@ void invert_screen(struct vc_data *vc, int offset, int count, int viewed)
/* used by selection: complement pointer position */ /* used by selection: complement pointer position */
void complement_pos(struct vc_data *vc, int offset) void complement_pos(struct vc_data *vc, int offset)
{ {
static unsigned short *p; static int old_offset = -1;
static unsigned short old; static unsigned short old;
static unsigned short oldx, oldy; static unsigned short oldx, oldy;
WARN_CONSOLE_UNLOCKED(); WARN_CONSOLE_UNLOCKED();
if (p) { if (old_offset != -1 && old_offset >= 0 &&
scr_writew(old, p); old_offset < vc->vc_screenbuf_size) {
scr_writew(old, screenpos(vc, old_offset, 1));
if (DO_UPDATE(vc)) if (DO_UPDATE(vc))
vc->vc_sw->con_putc(vc, old, oldy, oldx); vc->vc_sw->con_putc(vc, old, oldy, oldx);
} }
if (offset == -1)
p = NULL; old_offset = offset;
else {
if (offset != -1 && offset >= 0 &&
offset < vc->vc_screenbuf_size) {
unsigned short new; unsigned short new;
unsigned short *p;
p = screenpos(vc, offset, 1); p = screenpos(vc, offset, 1);
old = scr_readw(p); old = scr_readw(p);
new = old ^ vc->vc_complement_mask; new = old ^ vc->vc_complement_mask;
...@@ -459,6 +463,7 @@ void complement_pos(struct vc_data *vc, int offset) ...@@ -459,6 +463,7 @@ void complement_pos(struct vc_data *vc, int offset)
vc->vc_sw->con_putc(vc, new, oldy, oldx); vc->vc_sw->con_putc(vc, new, oldy, oldx);
} }
} }
} }
static void insert_char(struct vc_data *vc, unsigned int nr) static void insert_char(struct vc_data *vc, unsigned int nr)
......
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