Message ID | 20181024193713.15625-1-digetx@gmail.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Series | [v1] hwmon: Fix double-free in __hwmon_device_register() | expand |
Quoting Dmitry Osipenko <digetx@gmail.com>: > Fix double-free that happens when thermal zone setup fails, see KASAN log > below. > Good catch. I'll apply this as soon as I manage to convince AT&T to restore my internet service. Thanks, Guenter > ================================================================== > BUG: KASAN: double-free or invalid-free in > __hwmon_device_register+0x5dc/0xa7c > > CPU: 0 PID: 132 Comm: kworker/0:2 Tainted: G B > 4.19.0-rc8-next-20181016-00042-gb52cd80401e9-dirty #41 > Hardware name: NVIDIA Tegra SoC (Flattened Device Tree) > Workqueue: events deferred_probe_work_func > Backtrace: > [<c0110540>] (dump_backtrace) from [<c0110944>] (show_stack+0x20/0x24) > [<c0110924>] (show_stack) from [<c105cb08>] (dump_stack+0x9c/0xb0) > [<c105ca6c>] (dump_stack) from [<c02fdaec>] > (print_address_description+0x68/0x250) > [<c02fda84>] (print_address_description) from [<c02fd4ac>] > (kasan_report_invalid_free+0x68/0x88) > [<c02fd444>] (kasan_report_invalid_free) from [<c02fc85c>] > (__kasan_slab_free+0x1f4/0x200) > [<c02fc668>] (__kasan_slab_free) from [<c02fd0c0>] > (kasan_slab_free+0x14/0x18) > [<c02fd0ac>] (kasan_slab_free) from [<c02f9c6c>] (kfree+0x90/0x294) > [<c02f9bdc>] (kfree) from [<c0b41bbc>] (__hwmon_device_register+0x5dc/0xa7c) > [<c0b415e0>] (__hwmon_device_register) from [<c0b421e8>] > (hwmon_device_register_with_info+0xa0/0xa8) > [<c0b42148>] (hwmon_device_register_with_info) from [<c0b42324>] > (devm_hwmon_device_register_with_info+0x74/0xb4) > [<c0b422b0>] (devm_hwmon_device_register_with_info) from > [<c0b4481c>] (lm90_probe+0x414/0x578) > [<c0b44408>] (lm90_probe) from [<c0aeeff4>] (i2c_device_probe+0x35c/0x384) > [<c0aeec98>] (i2c_device_probe) from [<c08776cc>] (really_probe+0x290/0x3e4) > [<c087743c>] (really_probe) from [<c0877a2c>] > (driver_probe_device+0x80/0x1c4) > [<c08779ac>] (driver_probe_device) from [<c0877da8>] > (__device_attach_driver+0x104/0x11c) > [<c0877ca4>] (__device_attach_driver) from [<c0874dd8>] > (bus_for_each_drv+0xa4/0xc8) > [<c0874d34>] (bus_for_each_drv) from [<c08773b0>] > (__device_attach+0xf0/0x15c) > [<c08772c0>] (__device_attach) from [<c0877e24>] > (device_initial_probe+0x1c/0x20) > [<c0877e08>] (device_initial_probe) from [<c08762f4>] > (bus_probe_device+0xdc/0xec) > [<c0876218>] (bus_probe_device) from [<c0876a08>] > (deferred_probe_work_func+0xa8/0xd4) > [<c0876960>] (deferred_probe_work_func) from [<c01527c4>] > (process_one_work+0x3dc/0x96c) > [<c01523e8>] (process_one_work) from [<c01541e0>] (worker_thread+0x4ec/0x8bc) > [<c0153cf4>] (worker_thread) from [<c015b238>] (kthread+0x230/0x240) > [<c015b008>] (kthread) from [<c01010bc>] (ret_from_fork+0x14/0x38) > Exception stack(0xcf743fb0 to 0xcf743ff8) > 3fa0: 00000000 00000000 00000000 00000000 > 3fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 > 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000 > > Allocated by task 132: > kasan_kmalloc.part.1+0x58/0xf4 > kasan_kmalloc+0x90/0xa4 > kmem_cache_alloc_trace+0x90/0x2a0 > __hwmon_device_register+0xbc/0xa7c > hwmon_device_register_with_info+0xa0/0xa8 > devm_hwmon_device_register_with_info+0x74/0xb4 > lm90_probe+0x414/0x578 > i2c_device_probe+0x35c/0x384 > really_probe+0x290/0x3e4 > driver_probe_device+0x80/0x1c4 > __device_attach_driver+0x104/0x11c > bus_for_each_drv+0xa4/0xc8 > __device_attach+0xf0/0x15c > device_initial_probe+0x1c/0x20 > bus_probe_device+0xdc/0xec > deferred_probe_work_func+0xa8/0xd4 > process_one_work+0x3dc/0x96c > worker_thread+0x4ec/0x8bc > kthread+0x230/0x240 > ret_from_fork+0x14/0x38 > (null) > > Freed by task 132: > __kasan_slab_free+0x12c/0x200 > kasan_slab_free+0x14/0x18 > kfree+0x90/0x294 > hwmon_dev_release+0x1c/0x20 > device_release+0x4c/0xe8 > kobject_put+0xac/0x11c > device_unregister+0x2c/0x30 > __hwmon_device_register+0xa58/0xa7c > hwmon_device_register_with_info+0xa0/0xa8 > devm_hwmon_device_register_with_info+0x74/0xb4 > lm90_probe+0x414/0x578 > i2c_device_probe+0x35c/0x384 > really_probe+0x290/0x3e4 > driver_probe_device+0x80/0x1c4 > __device_attach_driver+0x104/0x11c > bus_for_each_drv+0xa4/0xc8 > __device_attach+0xf0/0x15c > device_initial_probe+0x1c/0x20 > bus_probe_device+0xdc/0xec > deferred_probe_work_func+0xa8/0xd4 > process_one_work+0x3dc/0x96c > worker_thread+0x4ec/0x8bc > kthread+0x230/0x240 > ret_from_fork+0x14/0x38 > (null) > > Cc: <stable@vger.kernel.org> # v4.15+ > Fixes: 47c332deb8e8 ("hwmon: Deal with errors from the thermal subsystem") > Signed-off-by: Dmitry Osipenko <digetx@gmail.com> > --- > drivers/hwmon/hwmon.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c > index 975c95169884..84f61cec6319 100644 > --- a/drivers/hwmon/hwmon.c > +++ b/drivers/hwmon/hwmon.c > @@ -649,8 +649,10 @@ __hwmon_device_register(struct device *dev, > const char *name, void *drvdata, > if (info[i]->config[j] & HWMON_T_INPUT) { > err = hwmon_thermal_add_sensor(dev, > hwdev, j); > - if (err) > - goto free_device; > + if (err) { > + device_unregister(hdev); > + goto ida_remove; > + } > } > } > } > @@ -658,8 +660,6 @@ __hwmon_device_register(struct device *dev, > const char *name, void *drvdata, > > return hdev; > > -free_device: > - device_unregister(hdev); > free_hwmon: > kfree(hwdev); > ida_remove: > -- > 2.19.0
On 10/25/18 3:15 AM, linux@roeck-us.net wrote: > > Quoting Dmitry Osipenko <digetx@gmail.com>: > >> Fix double-free that happens when thermal zone setup fails, see KASAN log >> below. >> > > Good catch. I'll apply this as soon as I manage to convince AT&T to restore > my internet service. Cool, thanks!
================================================================== BUG: KASAN: double-free or invalid-free in __hwmon_device_register+0x5dc/0xa7c CPU: 0 PID: 132 Comm: kworker/0:2 Tainted: G B 4.19.0-rc8-next-20181016-00042-gb52cd80401e9-dirty #41 Hardware name: NVIDIA Tegra SoC (Flattened Device Tree) Workqueue: events deferred_probe_work_func Backtrace: [<c0110540>] (dump_backtrace) from [<c0110944>] (show_stack+0x20/0x24) [<c0110924>] (show_stack) from [<c105cb08>] (dump_stack+0x9c/0xb0) [<c105ca6c>] (dump_stack) from [<c02fdaec>] (print_address_description+0x68/0x250) [<c02fda84>] (print_address_description) from [<c02fd4ac>] (kasan_report_invalid_free+0x68/0x88) [<c02fd444>] (kasan_report_invalid_free) from [<c02fc85c>] (__kasan_slab_free+0x1f4/0x200) [<c02fc668>] (__kasan_slab_free) from [<c02fd0c0>] (kasan_slab_free+0x14/0x18) [<c02fd0ac>] (kasan_slab_free) from [<c02f9c6c>] (kfree+0x90/0x294) [<c02f9bdc>] (kfree) from [<c0b41bbc>] (__hwmon_device_register+0x5dc/0xa7c) [<c0b415e0>] (__hwmon_device_register) from [<c0b421e8>] (hwmon_device_register_with_info+0xa0/0xa8) [<c0b42148>] (hwmon_device_register_with_info) from [<c0b42324>] (devm_hwmon_device_register_with_info+0x74/0xb4) [<c0b422b0>] (devm_hwmon_device_register_with_info) from [<c0b4481c>] (lm90_probe+0x414/0x578) [<c0b44408>] (lm90_probe) from [<c0aeeff4>] (i2c_device_probe+0x35c/0x384) [<c0aeec98>] (i2c_device_probe) from [<c08776cc>] (really_probe+0x290/0x3e4) [<c087743c>] (really_probe) from [<c0877a2c>] (driver_probe_device+0x80/0x1c4) [<c08779ac>] (driver_probe_device) from [<c0877da8>] (__device_attach_driver+0x104/0x11c) [<c0877ca4>] (__device_attach_driver) from [<c0874dd8>] (bus_for_each_drv+0xa4/0xc8) [<c0874d34>] (bus_for_each_drv) from [<c08773b0>] (__device_attach+0xf0/0x15c) [<c08772c0>] (__device_attach) from [<c0877e24>] (device_initial_probe+0x1c/0x20) [<c0877e08>] (device_initial_probe) from [<c08762f4>] (bus_probe_device+0xdc/0xec) [<c0876218>] (bus_probe_device) from [<c0876a08>] (deferred_probe_work_func+0xa8/0xd4) [<c0876960>] (deferred_probe_work_func) from [<c01527c4>] (process_one_work+0x3dc/0x96c) [<c01523e8>] (process_one_work) from [<c01541e0>] (worker_thread+0x4ec/0x8bc) [<c0153cf4>] (worker_thread) from [<c015b238>] (kthread+0x230/0x240) [<c015b008>] (kthread) from [<c01010bc>] (ret_from_fork+0x14/0x38) Exception stack(0xcf743fb0 to 0xcf743ff8) 3fa0: 00000000 00000000 00000000 00000000 3fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000 Allocated by task 132: kasan_kmalloc.part.1+0x58/0xf4 kasan_kmalloc+0x90/0xa4 kmem_cache_alloc_trace+0x90/0x2a0 __hwmon_device_register+0xbc/0xa7c hwmon_device_register_with_info+0xa0/0xa8 devm_hwmon_device_register_with_info+0x74/0xb4 lm90_probe+0x414/0x578 i2c_device_probe+0x35c/0x384 really_probe+0x290/0x3e4 driver_probe_device+0x80/0x1c4 __device_attach_driver+0x104/0x11c bus_for_each_drv+0xa4/0xc8 __device_attach+0xf0/0x15c device_initial_probe+0x1c/0x20 bus_probe_device+0xdc/0xec deferred_probe_work_func+0xa8/0xd4 process_one_work+0x3dc/0x96c worker_thread+0x4ec/0x8bc kthread+0x230/0x240 ret_from_fork+0x14/0x38 (null) Freed by task 132: __kasan_slab_free+0x12c/0x200 kasan_slab_free+0x14/0x18 kfree+0x90/0x294 hwmon_dev_release+0x1c/0x20 device_release+0x4c/0xe8 kobject_put+0xac/0x11c device_unregister+0x2c/0x30 __hwmon_device_register+0xa58/0xa7c hwmon_device_register_with_info+0xa0/0xa8 devm_hwmon_device_register_with_info+0x74/0xb4 lm90_probe+0x414/0x578 i2c_device_probe+0x35c/0x384 really_probe+0x290/0x3e4 driver_probe_device+0x80/0x1c4 __device_attach_driver+0x104/0x11c bus_for_each_drv+0xa4/0xc8 __device_attach+0xf0/0x15c device_initial_probe+0x1c/0x20 bus_probe_device+0xdc/0xec deferred_probe_work_func+0xa8/0xd4 process_one_work+0x3dc/0x96c worker_thread+0x4ec/0x8bc kthread+0x230/0x240 ret_from_fork+0x14/0x38 (null) Cc: <stable@vger.kernel.org> # v4.15+ Fixes: 47c332deb8e8 ("hwmon: Deal with errors from the thermal subsystem") Signed-off-by: Dmitry Osipenko <digetx@gmail.com> --- drivers/hwmon/hwmon.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index 975c95169884..84f61cec6319 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c @@ -649,8 +649,10 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata, if (info[i]->config[j] & HWMON_T_INPUT) { err = hwmon_thermal_add_sensor(dev, hwdev, j); - if (err) - goto free_device; + if (err) { + device_unregister(hdev); + goto ida_remove; + } } } } @@ -658,8 +660,6 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata, return hdev; -free_device: - device_unregister(hdev); free_hwmon: kfree(hwdev); ida_remove: