From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from mail-ew0-f165.google.com ([209.85.219.165]:42837 "EHLO mail-ew0-f165.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754510AbZDKHu0 convert rfc822-to-8bit (ORCPT ); Sat, 11 Apr 2009 03:50:26 -0400 Received: by ewy9 with SMTP id 9so1423585ewy.37 for ; Sat, 11 Apr 2009 00:50:24 -0700 (PDT) From: Ivo van Doorn To: Herton Ronaldo Krzesinski Subject: Re: [PATCH] rt2x00: prevent double kfree when failing to register hardware Date: Sat, 11 Apr 2009 09:50:20 +0200 Cc: "linux-wireless" , "John W. Linville" References: <200904101805.14986.herton@mandriva.com.br> In-Reply-To: <200904101805.14986.herton@mandriva.com.br> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Message-Id: <200904110950.21334.IvDoorn@gmail.com> (sfid-20090411_095032_275945_F9F80ACE) Sender: linux-wireless-owner@vger.kernel.org List-ID: On Friday 10 April 2009, Herton Ronaldo Krzesinski wrote: > In a scenario where there isn't any firmware available, we will have = a > double kfree of rt2x00dev->spec.channels_info when ieee80211_register= _hw > returns an error status inside rt2x00lib_probe_hw. >=20 > The problem is that if ieee80211_register_hw fails, we call > rt2x00lib_remove_hw twice: > * first inside rt2x00lib_probe_hw upon failure of ieee80211_register_= hw > * error status is returned to rt2x00lib_probe_dev, which then sees it= and > calls in this case rt2x00lib_remove_dev that will again run > rt2x00lib_remove_hw >=20 > Prevent this avoiding calling rt2x00lib_remove_hw inside > rt2x00lib_probe_hw >=20 > Problem was detected with CONFIG_DEBUG_PAGEALLOC=3Dy, CONFIG_SLUB_DEB= UG=3Dy, > CONFIG_SLUB_DEBUG_ON=3Dy, that dumps this with no firmware available: >=20 > rt61pci 0000:00:07.0: PCI INT A -> GSI 19 (level, low) -> IRQ 19 > wmaster0 (rt61pci): not using net_device_ops yet > phy0: Selected rate control algorithm 'pid' > phy0: Failed to initialize wep: -2 > phy0 -> rt2x00lib_probe_dev: Error - Failed to initialize hw. > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D > BUG kmalloc-128: Object already free > ---------------------------------------------------------------------= -------- >=20 > INFO: Allocated in rt61pci_probe_hw+0x3e5/0x6e0 [rt61pci] age=3D340 c= pu=3D0 pid=3D21 > INFO: Freed in rt2x00lib_remove_hw+0x59/0x70 [rt2x00lib] age=3D0 cpu=3D= 0 pid=3D21 > INFO: Slab 0xc13ac3e0 objects=3D23 used=3D10 fp=3D0xdd59f6e0 flags=3D= 0x400000c3 > INFO: Object 0xdd59f6e0 @offset=3D1760 fp=3D0xdd59f790 >=20 > Bytes b4 0xdd59f6d0: 15 00 00 00 b2 8a fb ff 5a 5a 5a 5a 5a 5a 5a 5a= ....=B2.=FB=FFZZZZZZZZ > Object 0xdd59f6e0: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b= kkkkkkkkkkkkkkkk > Object 0xdd59f6f0: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b= kkkkkkkkkkkkkkkk > Object 0xdd59f700: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b= kkkkkkkkkkkkkkkk > Object 0xdd59f710: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b= kkkkkkkkkkkkkkkk > Object 0xdd59f720: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b= kkkkkkkkkkkkkkkk > Object 0xdd59f730: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b= kkkkkkkkkkkkkkkk > Object 0xdd59f740: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b= kkkkkkkkkkkkkkkk > Object 0xdd59f750: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5= kkkkkkkkkkkkkkk=A5 > Redzone 0xdd59f760: bb bb bb bb = =BB=BB=BB=BB > Padding 0xdd59f788: 5a 5a 5a 5a 5a 5a 5a 5a = ZZZZZZZZ > Pid: 21, comm: stage1 Not tainted 2.6.29.1-desktop-1.1mnb #1 > Call Trace: > [] print_trailer+0xd3/0x120 > [] object_err+0x37/0x50 > [] __slab_free+0xe7/0x2f0 > [] kfree+0x7e/0xd0 > [] ? rt2x00lib_remove_hw+0x59/0x70 [rt2x00lib] > [] ? rt2x00lib_remove_hw+0x59/0x70 [rt2x00lib] > [] rt2x00lib_remove_hw+0x59/0x70 [rt2x00lib] > [] rt2x00lib_remove_dev+0x37/0x50 [rt2x00lib] > [] rt2x00lib_probe_dev+0x1a7/0x3b0 [rt2x00lib] > [] rt2x00pci_probe+0xdf/0x1ee [rt2x00pci] > [] local_pci_probe+0xe/0x10 > [] pci_device_probe+0x60/0x80 > [] driver_probe_device+0x9a/0x2e0 > [] __driver_attach+0x89/0x90 > [] bus_for_each_dev+0x4b/0x70 > [] ? pci_device_remove+0x0/0x40 > [] driver_attach+0x19/0x20 > [] ? __driver_attach+0x0/0x90 > [] bus_add_driver+0x1cf/0x2a0 > [] ? pci_device_remove+0x0/0x40 > [] driver_register+0x69/0x140 > [] __pci_register_driver+0x40/0x80 > [] ? rt61pci_init+0x0/0x19 [rt61pci] > [] rt61pci_init+0x17/0x19 [rt61pci] > [] do_one_initcall+0x26/0x1c0 > [] ? slab_pad_check+0x3c/0x120 > [] ? slab_pad_check+0x3c/0x120 > [] ? check_object+0xda/0x210 > [] ? percpu_free+0x46/0x50 > [] ? __slab_free+0x22e/0x2f0 > [] ? percpu_free+0x46/0x50 > [] ? percpu_free+0x46/0x50 > [] ? percpu_free+0x46/0x50 > [] ? stop_machine_destroy+0x3c/0x40 > [] ? load_module+0xa5/0x1c50 > [] ? rt61pci_eepromregister_read+0x0/0x40 [rt61pci] > [] ? rt2x00pci_write_tx_data+0x0/0x90 [rt2x00pci] > [] ? mutex_lock+0xb/0x20 > [] ? mutex_lock+0xb/0x20 > [] ? tracepoint_update_probe_range+0x76/0xa0 > [] ? tracepoint_module_notify+0x2f/0x40 > [] ? notifier_call_chain+0x2d/0x70 > [] ? __blocking_notifier_call_chain+0x4d/0x60 > [] ? blocking_notifier_call_chain+0x1a/0x20 > [] sys_init_module+0x96/0x1d0 > [] ? sys_munmap+0x46/0x60 > [] syscall_call+0x7/0xb > FIX kmalloc-128: Object at 0xdd59f6e0 not freed > rt61pci 0000:00:07.0: PCI INT A disabled > rt61pci: probe of 0000:00:07.0 failed with error -2 >=20 > Signed-off-by: Herton Ronaldo Krzesinski Acked-by: Ivo van Doorn --- John please queue this for 2.6.30 as well. Thanks. > --- > drivers/net/wireless/rt2x00/rt2x00dev.c | 4 +--- > 1 files changed, 1 insertions(+), 3 deletions(-) >=20 > diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wi= reless/rt2x00/rt2x00dev.c > index 05f94e2..5752aaa 100644 > --- a/drivers/net/wireless/rt2x00/rt2x00dev.c > +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c > @@ -646,10 +646,8 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev = *rt2x00dev) > * Register HW. > */ > status =3D ieee80211_register_hw(rt2x00dev->hw); > - if (status) { > - rt2x00lib_remove_hw(rt2x00dev); > + if (status) > return status; > - } > =20 > set_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags); > =20 -- To unsubscribe from this list: send the line "unsubscribe linux-wireles= s" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html