On Mon, May 20, 2019 at 10:55:40PM -0400, Nicolas Pitre wrote: > As soon as you release the lock, another thread could come along and > start using the memory pointed by vc_cons[currcons].d you're about to > free here. This is unlikely for an initcall, but still. > > You should consider this ordering instead: > > err_vc_screenbuf: > kfree(vc); > vc_cons[currcons].d = NULL; > err_vc: > console_unlock(); > return -ENOMEM; In function con_init(), the pointer variable vc_cons[currcons].d, vc and vc->vc_screenbuf is allocated a memory space via kzalloc(). And they are used in the following codes. However, when there is a memory allocation error, kzalloc() can fail. Thus null pointer (vc_cons[currcons].d, vc and vc->vc_screenbuf) dereference may happen. And it will cause the kernel to crash. Therefore, we should check return value and handle the error. Further,the loop condition MIN_NR_CONSOLES is defined as 1 in include/uapi/linux/vt.h and it is not changed. So there is no need to unwind the loop.
Signed-off-by: Gen Zhang <blackgod016...@gmail.com> --- diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index fdd12f8..ea47eb3 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -3350,10 +3350,14 @@ static int __init con_init(void) for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) { vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT); + if (!vc) + goto err_vc; INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); tty_port_init(&vc->port); visual_init(vc, currcons, 1); vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT); + if (!vc->vc_screenbuf) + goto err_vc_screenbuf; vc_init(vc, vc->vc_rows, vc->vc_cols, currcons || !vc->vc_sw->con_save_screen); } @@ -3375,6 +3379,13 @@ static int __init con_init(void) register_console(&vt_console_driver); #endif return 0; +err_vc_screenbuf: + kfree(vc); + vc_cons[currcons].d = NULL; +err_vc: + console_unlock(); + return -ENOMEM; + } console_initcall(con_init); ---