Skip to content

Commit a1ad1cc

Browse files
Grzegorz Halatgregkh
Grzegorz Halat
authored andcommitted
vt/fbcon: deinitialize resources in visual_init() after failed memory allocation
After memory allocation failure vc_allocate() doesn't clean up data which has been initialized in visual_init(). In case of fbcon this leads to divide-by-0 in fbcon_init() on next open of the same tty. memory allocation in vc_allocate() may fail here: 1097: vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_KERNEL); on next open() fbcon_init() skips vc_font.data initialization: 1088: if (!p->fontdata) { division by zero in fbcon_init() happens here: 1149: new_cols /= vc->vc_font.width; Additional check is needed in fbcon_deinit() to prevent usage of uninitialized vc_screenbuf: 1251: if (vc->vc_hi_font_mask && vc->vc_screenbuf) 1252: set_vc_hi_font(vc, false); Crash: #6 [ffffc90001eafa60] divide_error at ffffffff81a00be4 [exception RIP: fbcon_init+463] RIP: ffffffff814b860f RSP: ffffc90001eafb18 RFLAGS: 00010246 ... #7 [ffffc90001eafb60] visual_init at ffffffff8154c36e #8 [ffffc90001eafb80] vc_allocate at ffffffff8154f53c #9 [ffffc90001eafbc8] con_install at ffffffff8154f624 ... Signed-off-by: Grzegorz Halat <[email protected]> Reviewed-by: Oleksandr Natalenko <[email protected]> Acked-by: Bartlomiej Zolnierkiewicz <[email protected]> Cc: stable <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 5d24f45 commit a1ad1cc

File tree

2 files changed

+10
-3
lines changed

2 files changed

+10
-3
lines changed

drivers/tty/vt/vt.c

+9-2
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,13 @@ static void visual_init(struct vc_data *vc, int num, int init)
10561056
vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row;
10571057
}
10581058

1059+
1060+
static void visual_deinit(struct vc_data *vc)
1061+
{
1062+
vc->vc_sw->con_deinit(vc);
1063+
module_put(vc->vc_sw->owner);
1064+
}
1065+
10591066
int vc_allocate(unsigned int currcons) /* return 0 on success */
10601067
{
10611068
struct vt_notifier_param param;
@@ -1103,6 +1110,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
11031110

11041111
return 0;
11051112
err_free:
1113+
visual_deinit(vc);
11061114
kfree(vc);
11071115
vc_cons[currcons].d = NULL;
11081116
return -ENOMEM;
@@ -1331,9 +1339,8 @@ struct vc_data *vc_deallocate(unsigned int currcons)
13311339
param.vc = vc = vc_cons[currcons].d;
13321340
atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
13331341
vcs_remove_sysfs(currcons);
1334-
vc->vc_sw->con_deinit(vc);
1342+
visual_deinit(vc);
13351343
put_pid(vc->vt_pid);
1336-
module_put(vc->vc_sw->owner);
13371344
vc_uniscr_set(vc, NULL);
13381345
kfree(vc->vc_screenbuf);
13391346
vc_cons[currcons].d = NULL;

drivers/video/fbdev/core/fbcon.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1248,7 +1248,7 @@ static void fbcon_deinit(struct vc_data *vc)
12481248
if (free_font)
12491249
vc->vc_font.data = NULL;
12501250

1251-
if (vc->vc_hi_font_mask)
1251+
if (vc->vc_hi_font_mask && vc->vc_screenbuf)
12521252
set_vc_hi_font(vc, false);
12531253

12541254
if (!con_is_bound(&fb_con))

0 commit comments

Comments
 (0)