Skip to content

Commit 1782829

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 a327074 commit 1782829

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
@@ -465,20 +465,14 @@ static struct sdio_driver brcmf_sdmmc_driver = {
465465

466466
static int brcmf_sdio_pd_probe(struct platform_device *pdev)
467467
{
468-
int ret;
469-
470468
brcmf_dbg(SDIO, "Enter\n");
471469

472470
brcmfmac_sdio_pdata = pdev->dev.platform_data;
473471

474472
if (brcmfmac_sdio_pdata->power_on)
475473
brcmfmac_sdio_pdata->power_on();
476474

477-
ret = sdio_register_driver(&brcmf_sdmmc_driver);
478-
if (ret)
479-
brcmf_err("sdio_register_driver failed: %d\n", ret);
480-
481-
return ret;
475+
return 0;
482476
}
483477

484478
static int brcmf_sdio_pd_remove(struct platform_device *pdev)
@@ -501,6 +495,15 @@ static struct platform_driver brcmf_sdio_pd = {
501495
}
502496
};
503497

498+
void brcmf_sdio_register(void)
499+
{
500+
int ret;
501+
502+
ret = sdio_register_driver(&brcmf_sdmmc_driver);
503+
if (ret)
504+
brcmf_err("sdio_register_driver failed: %d\n", ret);
505+
}
506+
504507
void brcmf_sdio_exit(void)
505508
{
506509
brcmf_dbg(SDIO, "Enter\n");
@@ -511,18 +514,13 @@ void brcmf_sdio_exit(void)
511514
sdio_unregister_driver(&brcmf_sdmmc_driver);
512515
}
513516

514-
void brcmf_sdio_init(void)
517+
void __init brcmf_sdio_init(void)
515518
{
516519
int ret;
517520

518521
brcmf_dbg(SDIO, "Enter\n");
519522

520523
ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe);
521-
if (ret == -ENODEV) {
522-
brcmf_dbg(SDIO, "No platform data available, registering without.\n");
523-
ret = sdio_register_driver(&brcmf_sdmmc_driver);
524-
}
525-
526-
if (ret)
527-
brcmf_err("driver registration failed: %d\n", ret);
524+
if (ret == -ENODEV)
525+
brcmf_dbg(SDIO, "No platform data available.\n");
528526
}

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
@@ -1020,21 +1020,23 @@ u32 brcmf_get_chip_info(struct brcmf_if *ifp)
10201020
return bus->chip << 4 | bus->chiprev;
10211021
}
10221022

1023-
static void brcmf_driver_init(struct work_struct *work)
1023+
static void brcmf_driver_register(struct work_struct *work)
10241024
{
1025-
brcmf_debugfs_init();
1026-
10271025
#ifdef CONFIG_BRCMFMAC_SDIO
1028-
brcmf_sdio_init();
1026+
brcmf_sdio_register();
10291027
#endif
10301028
#ifdef CONFIG_BRCMFMAC_USB
1031-
brcmf_usb_init();
1029+
brcmf_usb_register();
10321030
#endif
10331031
}
1034-
static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init);
1032+
static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register);
10351033

10361034
static int __init brcmfmac_module_init(void)
10371035
{
1036+
brcmf_debugfs_init();
1037+
#ifdef CONFIG_BRCMFMAC_SDIO
1038+
brcmf_sdio_init();
1039+
#endif
10381040
if (!schedule_work(&brcmf_driver_work))
10391041
return -EBUSY;
10401042

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1540,7 +1540,7 @@ void brcmf_usb_exit(void)
15401540
brcmf_release_fw(&fw_image_list);
15411541
}
15421542

1543-
void brcmf_usb_init(void)
1543+
void brcmf_usb_register(void)
15441544
{
15451545
brcmf_dbg(USB, "Enter\n");
15461546
INIT_LIST_HEAD(&fw_image_list);

0 commit comments

Comments
 (0)