Skip to content

Commit 3fe79a2

Browse files
Murad Masimovjmberg-intel
authored andcommitted
wifi: plfxlc: Fix error handling in usb driver probe
If probe fails before ieee80211_register_hw() is successfully done, ieee80211_unregister_hw() will be called anyway. This may lead to various bugs as the implementation of ieee80211_unregister_hw() assumes that ieee80211_register_hw() has been called. Divide error handling section into relevant subsections, so that ieee80211_unregister_hw() is called only when it is appropriate. Correct the order of the calls: ieee80211_unregister_hw() should go before plfxlc_mac_release(). Also move ieee80211_free_hw() to plfxlc_mac_release() as it supposed to be the opposite to plfxlc_mac_alloc_hw() that calls ieee80211_alloc_hw(). Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Fixes: 68d57a0 ("wireless: add plfxlc driver for pureLiFi X, XL, XC devices") Signed-off-by: Murad Masimov <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Johannes Berg <[email protected]>
1 parent f8bf97a commit 3fe79a2

File tree

3 files changed

+21
-21
lines changed

3 files changed

+21
-21
lines changed

drivers/net/wireless/purelifi/plfxlc/mac.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,6 @@ int plfxlc_mac_init_hw(struct ieee80211_hw *hw)
9999
return r;
100100
}
101101

102-
void plfxlc_mac_release(struct plfxlc_mac *mac)
103-
{
104-
plfxlc_chip_release(&mac->chip);
105-
}
106-
107102
int plfxlc_op_start(struct ieee80211_hw *hw)
108103
{
109104
plfxlc_hw_mac(hw)->chip.usb.initialized = 1;
@@ -756,3 +751,9 @@ struct ieee80211_hw *plfxlc_mac_alloc_hw(struct usb_interface *intf)
756751
SET_IEEE80211_DEV(hw, &intf->dev);
757752
return hw;
758753
}
754+
755+
void plfxlc_mac_release_hw(struct ieee80211_hw *hw)
756+
{
757+
plfxlc_chip_release(&plfxlc_hw_mac(hw)->chip);
758+
ieee80211_free_hw(hw);
759+
}

drivers/net/wireless/purelifi/plfxlc/mac.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ static inline u8 *plfxlc_mac_get_perm_addr(struct plfxlc_mac *mac)
168168
}
169169

170170
struct ieee80211_hw *plfxlc_mac_alloc_hw(struct usb_interface *intf);
171-
void plfxlc_mac_release(struct plfxlc_mac *mac);
171+
void plfxlc_mac_release_hw(struct ieee80211_hw *hw);
172172

173173
int plfxlc_mac_preinit_hw(struct ieee80211_hw *hw, const u8 *hw_address);
174174
int plfxlc_mac_init_hw(struct ieee80211_hw *hw);

drivers/net/wireless/purelifi/plfxlc/usb.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ static int probe(struct usb_interface *intf,
604604
r = plfxlc_upload_mac_and_serial(intf, hw_address, serial_number);
605605
if (r) {
606606
dev_err(&intf->dev, "MAC and Serial upload failed (%d)\n", r);
607-
goto error;
607+
goto error_free_hw;
608608
}
609609

610610
chip->unit_type = STA;
@@ -613,13 +613,13 @@ static int probe(struct usb_interface *intf,
613613
r = plfxlc_mac_preinit_hw(hw, hw_address);
614614
if (r) {
615615
dev_err(&intf->dev, "Init mac failed (%d)\n", r);
616-
goto error;
616+
goto error_free_hw;
617617
}
618618

619619
r = ieee80211_register_hw(hw);
620620
if (r) {
621621
dev_err(&intf->dev, "Register device failed (%d)\n", r);
622-
goto error;
622+
goto error_free_hw;
623623
}
624624

625625
if ((le16_to_cpu(interface_to_usbdev(intf)->descriptor.idVendor) ==
@@ -632,7 +632,7 @@ static int probe(struct usb_interface *intf,
632632
}
633633
if (r != 0) {
634634
dev_err(&intf->dev, "FPGA download failed (%d)\n", r);
635-
goto error;
635+
goto error_unreg_hw;
636636
}
637637

638638
tx->mac_fifo_full = 0;
@@ -642,29 +642,29 @@ static int probe(struct usb_interface *intf,
642642
r = plfxlc_usb_init_hw(usb);
643643
if (r < 0) {
644644
dev_err(&intf->dev, "usb_init_hw failed (%d)\n", r);
645-
goto error;
645+
goto error_unreg_hw;
646646
}
647647

648648
msleep(PLF_MSLEEP_TIME);
649649
r = plfxlc_chip_switch_radio(chip, PLFXLC_RADIO_ON);
650650
if (r < 0) {
651651
dev_dbg(&intf->dev, "chip_switch_radio_on failed (%d)\n", r);
652-
goto error;
652+
goto error_unreg_hw;
653653
}
654654

655655
msleep(PLF_MSLEEP_TIME);
656656
r = plfxlc_chip_set_rate(chip, 8);
657657
if (r < 0) {
658658
dev_dbg(&intf->dev, "chip_set_rate failed (%d)\n", r);
659-
goto error;
659+
goto error_unreg_hw;
660660
}
661661

662662
msleep(PLF_MSLEEP_TIME);
663663
r = plfxlc_usb_wreq(usb->ez_usb,
664664
hw_address, ETH_ALEN, USB_REQ_MAC_WR);
665665
if (r < 0) {
666666
dev_dbg(&intf->dev, "MAC_WR failure (%d)\n", r);
667-
goto error;
667+
goto error_unreg_hw;
668668
}
669669

670670
plfxlc_chip_enable_rxtx(chip);
@@ -691,12 +691,12 @@ static int probe(struct usb_interface *intf,
691691
plfxlc_mac_init_hw(hw);
692692
usb->initialized = true;
693693
return 0;
694+
695+
error_unreg_hw:
696+
ieee80211_unregister_hw(hw);
697+
error_free_hw:
698+
plfxlc_mac_release_hw(hw);
694699
error:
695-
if (hw) {
696-
plfxlc_mac_release(plfxlc_hw_mac(hw));
697-
ieee80211_unregister_hw(hw);
698-
ieee80211_free_hw(hw);
699-
}
700700
dev_err(&intf->dev, "pureLifi:Device error");
701701
return r;
702702
}
@@ -730,8 +730,7 @@ static void disconnect(struct usb_interface *intf)
730730
*/
731731
usb_reset_device(interface_to_usbdev(intf));
732732

733-
plfxlc_mac_release(mac);
734-
ieee80211_free_hw(hw);
733+
plfxlc_mac_release_hw(hw);
735734
}
736735

737736
static void plfxlc_usb_resume(struct plfxlc_usb *usb)

0 commit comments

Comments
 (0)