Nasty memory scribble in console.c

Bernd Schmidt (crux@Pool.Informatik.RWTH-Aachen.DE)
Mon, 20 Jul 1998 12:06:20 +0200 (MET DST)


I've found a nasty bug in console.c yesterday. My system oopsed during boot,
while running SVGATextMode. The oops happened in kill_pg_info, and ebx
contained 0x07200720 (twice video_erase_char) instead of a pointer to a
process structure. It turns out that this bit in vc_resize

if (scr_end > nl)
scr_memsetw((void *) nl, video_erase_char, scr_end - nl);

makes no sense if vgacon is used, because scr_end will point to VGA memory
and nl points to kmalloced memory. The patch below corrects the problem.

Bernd

--- ./drivers/char/console.c.orig-1 Sat Jul 18 19:36:13 1998
+++ ./drivers/char/console.c Sun Jul 19 11:42:33 1998
@@ -561,11 +561,8 @@ int vc_resize(unsigned int lines, unsign
unsigned int first, unsigned int last)
{
unsigned int cc, ll, ss, sr, todo = 0;
- unsigned int occ, oll, oss, osr;
- unsigned short *p;
unsigned int currcons = fg_console, i;
unsigned short *newscreens[MAX_NR_CONSOLES];
- unsigned long ol, nl, rlth, rrem;

cc = (cols ? cols : video_num_columns);
ll = (lines ? lines : video_num_lines);
@@ -577,7 +574,7 @@ int vc_resize(unsigned int lines, unsign
(cc == video_num_columns && ll == video_num_lines))
newscreens[currcons] = NULL;
else {
- p = (unsigned short *) kmalloc(ss, GFP_USER);
+ unsigned short *p = (unsigned short *) kmalloc(ss, GFP_USER);
if (!p) {
for (i = 0; i< currcons; i++)
if (newscreens[i])
@@ -592,6 +589,8 @@ int vc_resize(unsigned int lines, unsign
return 0;

for (currcons = first; currcons <= last; currcons++) {
+ unsigned int occ, oll, oss, osr;
+ unsigned long ol, nl, nlend, rlth, rrem;
if (!newscreens[currcons] || !vc_cons_allocated(currcons))
continue;

@@ -609,10 +608,12 @@ int vc_resize(unsigned int lines, unsign
rrem = sr - rlth;
ol = origin;
nl = (long) newscreens[currcons];
+ nlend = nl + ss;
if (ll < oll)
ol += (oll - ll) * osr;

update_attr(currcons);
+
while (ol < scr_end) {
scr_memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
if (rrem)
@@ -620,16 +621,14 @@ int vc_resize(unsigned int lines, unsign
ol += osr;
nl += sr;
}
-
+ if (nlend > nl)
+ scr_memsetw((void *) nl, video_erase_char, nlend - nl);
if (kmalloced)
kfree_s(screenbuf, oss);
screenbuf = newscreens[currcons];
kmalloced = 1;
screenbuf_size = ss;
set_origin(currcons);
-
- if (scr_end > nl)
- scr_memsetw((void *) nl, video_erase_char, scr_end - nl);

/* do part of a reset_terminal() */
top = 0;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html