Skip to content

Commit 37afef3

Browse files
Arend van Sprielgregkh
Arend van Spriel
authored andcommitted
brcmfmac: obtain platform data upon module initialization
commit db4efbb upstream. The driver uses platform_driver_probe() to obtain platform data if any. However, that function is placed in the .init section so it must be called upon driver module initialization. The problem was reported by Fenguang Wu resulting in a kernel oops because the .init section was already freed. [ 48.966342] Switched to clocksource tsc [ 48.970002] kernel tried to execute NX-protected page - exploit attempt? (uid: 0) [ 48.970851] BUG: unable to handle kernel paging request at ffffffff82196446 [ 48.970957] IP: [<ffffffff82196446>] classes_init+0x26/0x26 [ 48.970957] PGD 1e76067 PUD 1e77063 PMD f388063 PTE 8000000002196163 [ 48.970957] Oops: 0011 [#1] [ 48.970957] CPU: 0 PID: 17 Comm: kworker/0:1 Not tainted 3.11.0-rc7-00444-gc52dd7f #23 [ 48.970957] Workqueue: events brcmf_driver_init [ 48.970957] task: ffff8800001d2000 ti: ffff8800001d4000 task.ti: ffff8800001d4000 [ 48.970957] RIP: 0010:[<ffffffff82196446>] [<ffffffff82196446>] classes_init+0x26/0x26 [ 48.970957] RSP: 0000:ffff8800001d5d40 EFLAGS: 00000286 [ 48.970957] RAX: 0000000000000001 RBX: ffffffff820c5620 RCX: 0000000000000000 [ 48.970957] RDX: 0000000000000001 RSI: ffffffff816f7380 RDI: ffffffff820c56c0 [ 48.970957] RBP: ffff8800001d5d50 R08: ffff8800001d2508 R09: 0000000000000002 [ 48.970957] R10: 0000000000000000 R11: 0001f7ce298c5620 R12: ffff8800001c76b0 [ 48.970957] R13: ffffffff81e91d40 R14: 0000000000000000 R15: ffff88000e0ce300 [ 48.970957] FS: 0000000000000000(0000) GS:ffffffff81e84000(0000) knlGS:0000000000000000 [ 48.970957] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 48.970957] CR2: ffffffff82196446 CR3: 0000000001e75000 CR4: 00000000000006b0 [ 48.970957] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 48.970957] DR3: 0000000000000000 DR6: 0000000000000000 DR7: 0000000000000000 [ 48.970957] Stack: [ 48.970957] ffffffff816f7df8 ffffffff820c5620 ffff8800001d5d60 ffffffff816eeec9 [ 48.970957] ffff8800001d5de0 ffffffff81073dc5 ffffffff81073d68 ffff8800001d5db8 [ 48.970957] 0000000000000086 ffffffff820c5620 ffffffff824f7fd0 0000000000000000 [ 48.970957] Call Trace: [ 48.970957] [<ffffffff816f7df8>] ? brcmf_sdio_init+0x18/0x70 [ 48.970957] [<ffffffff816eeec9>] brcmf_driver_init+0x9/0x10 [ 48.970957] [<ffffffff81073dc5>] process_one_work+0x1d5/0x480 [ 48.970957] [<ffffffff81073d68>] ? process_one_work+0x178/0x480 [ 48.970957] [<ffffffff81074188>] worker_thread+0x118/0x3a0 [ 48.970957] [<ffffffff81074070>] ? process_one_work+0x480/0x480 [ 48.970957] [<ffffffff8107aa17>] kthread+0xe7/0xf0 [ 48.970957] [<ffffffff810829f7>] ? finish_task_switch.constprop.57+0x37/0xd0 [ 48.970957] [<ffffffff8107a930>] ? __kthread_parkme+0x80/0x80 [ 48.970957] [<ffffffff81a6923a>] ret_from_fork+0x7a/0xb0 [ 48.970957] [<ffffffff8107a930>] ? __kthread_parkme+0x80/0x80 [ 48.970957] Code: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc <cc> cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc [ 48.970957] RIP [<ffffffff82196446>] classes_init+0x26/0x26 [ 48.970957] RSP <ffff8800001d5d40> [ 48.970957] CR2: ffffffff82196446 [ 48.970957] ---[ end trace 62980817cd525f14 ]--- Reported-by: Fengguang Wu <[email protected]> Reviewed-by: Hante Meuleman <[email protected]> Reviewed-by: Pieter-Paul Giesberts <[email protected]> Tested-by: Fengguang Wu <[email protected]> Signed-off-by: Arend van Spriel <[email protected]> Signed-off-by: John W. Linville <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 9abd30b commit 37afef3

File tree

4 files changed

+24
-23
lines changed

4 files changed

+24
-23
lines changed

drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -575,20 +575,14 @@ static struct sdio_driver brcmf_sdmmc_driver = {
575575

576576
static int brcmf_sdio_pd_probe(struct platform_device *pdev)
577577
{
578-
int ret;
579-
580578
brcmf_dbg(SDIO, "Enter\n");
581579

582580
brcmfmac_sdio_pdata = pdev->dev.platform_data;
583581

584582
if (brcmfmac_sdio_pdata->power_on)
585583
brcmfmac_sdio_pdata->power_on();
586584

587-
ret = sdio_register_driver(&brcmf_sdmmc_driver);
588-
if (ret)
589-
brcmf_err("sdio_register_driver failed: %d\n", ret);
590-
591-
return ret;
585+
return 0;
592586
}
593587

594588
static int brcmf_sdio_pd_remove(struct platform_device *pdev)
@@ -610,6 +604,15 @@ static struct platform_driver brcmf_sdio_pd = {
610604
}
611605
};
612606

607+
void brcmf_sdio_register(void)
608+
{
609+
int ret;
610+
611+
ret = sdio_register_driver(&brcmf_sdmmc_driver);
612+
if (ret)
613+
brcmf_err("sdio_register_driver failed: %d\n", ret);
614+
}
615+
613616
void brcmf_sdio_exit(void)
614617
{
615618
brcmf_dbg(SDIO, "Enter\n");
@@ -620,18 +623,13 @@ void brcmf_sdio_exit(void)
620623
sdio_unregister_driver(&brcmf_sdmmc_driver);
621624
}
622625

623-
void brcmf_sdio_init(void)
626+
void __init brcmf_sdio_init(void)
624627
{
625628
int ret;
626629

627630
brcmf_dbg(SDIO, "Enter\n");
628631

629632
ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe);
630-
if (ret == -ENODEV) {
631-
brcmf_dbg(SDIO, "No platform data available, registering without.\n");
632-
ret = sdio_register_driver(&brcmf_sdmmc_driver);
633-
}
634-
635-
if (ret)
636-
brcmf_err("driver registration failed: %d\n", ret);
633+
if (ret == -ENODEV)
634+
brcmf_dbg(SDIO, "No platform data available.\n");
637635
}

drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,11 @@ extern int brcmf_bus_start(struct device *dev);
154154
#ifdef CONFIG_BRCMFMAC_SDIO
155155
extern void brcmf_sdio_exit(void);
156156
extern void brcmf_sdio_init(void);
157+
extern void brcmf_sdio_register(void);
157158
#endif
158159
#ifdef CONFIG_BRCMFMAC_USB
159160
extern void brcmf_usb_exit(void);
160-
extern void brcmf_usb_init(void);
161+
extern void brcmf_usb_register(void);
161162
#endif
162163

163164
#endif /* _BRCMF_BUS_H_ */

drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,21 +1034,23 @@ u32 brcmf_get_chip_info(struct brcmf_if *ifp)
10341034
return bus->chip << 4 | bus->chiprev;
10351035
}
10361036

1037-
static void brcmf_driver_init(struct work_struct *work)
1037+
static void brcmf_driver_register(struct work_struct *work)
10381038
{
1039-
brcmf_debugfs_init();
1040-
10411039
#ifdef CONFIG_BRCMFMAC_SDIO
1042-
brcmf_sdio_init();
1040+
brcmf_sdio_register();
10431041
#endif
10441042
#ifdef CONFIG_BRCMFMAC_USB
1045-
brcmf_usb_init();
1043+
brcmf_usb_register();
10461044
#endif
10471045
}
1048-
static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init);
1046+
static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register);
10491047

10501048
static int __init brcmfmac_module_init(void)
10511049
{
1050+
brcmf_debugfs_init();
1051+
#ifdef CONFIG_BRCMFMAC_SDIO
1052+
brcmf_sdio_init();
1053+
#endif
10521054
if (!schedule_work(&brcmf_driver_work))
10531055
return -EBUSY;
10541056

drivers/net/wireless/brcm80211/brcmfmac/usb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1532,7 +1532,7 @@ void brcmf_usb_exit(void)
15321532
brcmf_release_fw(&fw_image_list);
15331533
}
15341534

1535-
void brcmf_usb_init(void)
1535+
void brcmf_usb_register(void)
15361536
{
15371537
brcmf_dbg(USB, "Enter\n");
15381538
INIT_LIST_HEAD(&fw_image_list);

0 commit comments

Comments
 (0)