diff options
author | André Goddard Rosa <andre.goddard@gmail.com> | 2009-10-25 09:16:32 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-12-11 18:18:04 -0500 |
commit | 9e845abfc8a8973373821aa05302794fd254514b (patch) | |
tree | 0dbd44e16a4fbe9554d25b4dcbc17fea7207a933 | |
parent | 2a0785ea375fe93cd480599bb40d0c837ff72a2e (diff) |
serial: fix NULL pointer dereference
If kzalloc() or alloc_tty_driver() fails, we call:
put_tty_driver(normal = NULL).
Then:
put_tty_driver -> tty_driver_kref_put -> kref_put(&NULL->kref, ...)
Signed-off-by: André Goddard Rosa <andre.goddard@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/serial/serial_core.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index dcc72444e8e7..885eabe552cd 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -2344,7 +2344,7 @@ static const struct tty_operations uart_ops = { | |||
2344 | */ | 2344 | */ |
2345 | int uart_register_driver(struct uart_driver *drv) | 2345 | int uart_register_driver(struct uart_driver *drv) |
2346 | { | 2346 | { |
2347 | struct tty_driver *normal = NULL; | 2347 | struct tty_driver *normal; |
2348 | int i, retval; | 2348 | int i, retval; |
2349 | 2349 | ||
2350 | BUG_ON(drv->state); | 2350 | BUG_ON(drv->state); |
@@ -2354,13 +2354,12 @@ int uart_register_driver(struct uart_driver *drv) | |||
2354 | * we have a large number of ports to handle. | 2354 | * we have a large number of ports to handle. |
2355 | */ | 2355 | */ |
2356 | drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL); | 2356 | drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL); |
2357 | retval = -ENOMEM; | ||
2358 | if (!drv->state) | 2357 | if (!drv->state) |
2359 | goto out; | 2358 | goto out; |
2360 | 2359 | ||
2361 | normal = alloc_tty_driver(drv->nr); | 2360 | normal = alloc_tty_driver(drv->nr); |
2362 | if (!normal) | 2361 | if (!normal) |
2363 | goto out; | 2362 | goto out_kfree; |
2364 | 2363 | ||
2365 | drv->tty_driver = normal; | 2364 | drv->tty_driver = normal; |
2366 | 2365 | ||
@@ -2393,12 +2392,14 @@ int uart_register_driver(struct uart_driver *drv) | |||
2393 | } | 2392 | } |
2394 | 2393 | ||
2395 | retval = tty_register_driver(normal); | 2394 | retval = tty_register_driver(normal); |
2396 | out: | 2395 | if (retval >= 0) |
2397 | if (retval < 0) { | 2396 | return retval; |
2398 | put_tty_driver(normal); | 2397 | |
2399 | kfree(drv->state); | 2398 | put_tty_driver(normal); |
2400 | } | 2399 | out_kfree: |
2401 | return retval; | 2400 | kfree(drv->state); |
2401 | out: | ||
2402 | return -ENOMEM; | ||
2402 | } | 2403 | } |
2403 | 2404 | ||
2404 | /** | 2405 | /** |