Skip to content

kernel NULL pointer if sof_probe failed #494

Closed

Description

@bardliao

If sof_probe return error for some reason, sdev will be freed. But "sof-audio-pci" will not return error if sof_probe failed. It means snd_sof_runtime_suspend/resume and snd_sof_suspend/resume will be used with a null sdev which will cause kernel NULL pointer issue.
Below is an example. When hda_codec_i915_init() failed, sof_suspend() will die due to sdev = null.

[    3.374395] sof-audio-pci 0000:00:1f.3: PP capability, will probe DSP later.
[    3.374423] sof-audio-pci 0000:00:1f.3: error: no HDMI audio devices found
[    3.376052] sof-audio sof-audio: error: failed to probe DSP -19
[    3.377464] sdhci-pci 0000:00:14.5: SDHCI controller found [8086:34f8] (rev 0)
[    3.380780] BUG: unable to handle kernel NULL pointer dereference at 0000000000000140
[    3.382314] PGD 0 P4D 0 
[    3.383823] Oops: 0000 [#1] SMP PTI
[    3.385407] CPU: 1 PID: 17 Comm: kworker/1:0 Tainted: G        W         4.19.0-i2s-cac0c10e-+ #4
[    3.386910] Hardware name: Intel Corporation Ice Lake Client Platform/IceLake Y LPDDR4/4x T4 RVP, BIOS ICLSFWR1.R00.2212.A00.1805220806 05/22/2018
[    3.388430] Workqueue: pm pm_runtime_work
[    3.389928] RIP: 0010:sof_suspend+0x20/0x170 [snd_sof]
[    3.391450] Code: 66 2e 0f 1f 84 00 00 00 00 00 41 56 41 55 41 54 55 53 48 83 ec 08 48 8b 87 98 00 00 00 48 8b 40 08 4c 8b a0 a8 00 00 00 31 c0 <49> 8b 94 24 40 01 00 00 48 83 7a 48 00 0f 84 ee 00 00 00 4c 89 e7
[    3.393090] RSP: 0000:ffffa4d400d73d60 EFLAGS: 00010246
[    3.394739] RAX: 0000000000000000 RBX: ffff9baba677f8a8 RCX: 0000000000000000
[    3.396406] RDX: ffffffffc0301000 RSI: 0000000000000001 RDI: ffff9baba677f8a8
[    3.398049] RBP: 0000000000000000 R08: 00000000000007d0 R09: ffffa4d400d73df0
[    3.399716] R10: 0000000000000001 R11: fefefefefefefeff R12: 0000000000000000
[    3.401334] R13: ffff9baba677f800 R14: 0000000000000000 R15: 0000000000000000
[    3.402993] FS:  0000000000000000(0000) GS:ffff9baba8100000(0000) knlGS:0000000000000000
[    3.404631] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    3.406247] CR2: 0000000000000140 CR3: 00000001ec60a005 CR4: 0000000000760ee0
[    3.407880] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[    3.409472] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[    3.411023] PKRU: 55555554
[    3.412499] Call Trace:
[    3.413992]  ? __switch_to_asm+0x40/0x70
[    3.415535]  pci_pm_runtime_suspend+0x57/0x130
[    3.417013]  ? pci_pm_runtime_resume+0xa0/0xa0
[    3.418497]  __rpm_callback+0xb7/0x1b0
[    3.420018]  ? pci_pm_runtime_resume+0xa0/0xa0
[    3.421560]  rpm_callback+0x1a/0x70
[    3.423022]  ? pci_pm_runtime_resume+0xa0/0xa0
[    3.424514]  rpm_suspend+0x125/0x660
[    3.426053]  pm_runtime_work+0x75/0x80
[    3.427557]  process_one_work+0x1e3/0x3d0
[    3.429066]  worker_thread+0x28/0x3c0
[    3.430588]  ? set_worker_desc+0xb0/0xb0
[    3.432104]  kthread+0x10e/0x130
[    3.433550]  ? kthread_create_worker_on_cpu+0x70/0x70
[    3.434988]  ret_from_fork+0x35/0x40
[    3.436479] Modules linked in: sof_pci_dev snd_sof_intel_hda_common snd_sof_intel_hda snd_sof_intel_byt snd_sof_nocodec snd_sof_xtensa_dsp snd_sof snd_soc_acpi_intel_match snd_soc_acpi snd_hda_ext_core snd_hda_core snd_soc_core snd_pcm intel_lpss_pci(+) intel_lpss mfd_core efivarfs xhci_pci sdhci_pci cqhci sdhci xhci_hcd
[    3.439738] CR2: 0000000000000140
[    3.441323] ---[ end trace 03276d72c3920cd3 ]---
[    3.442989] RIP: 0010:sof_suspend+0x20/0x170 [snd_sof]
[    3.444627] Code: 66 2e 0f 1f 84 00 00 00 00 00 41 56 41 55 41 54 55 53 48 83 ec 08 48 8b 87 98 00 00 00 48 8b 40 08 4c 8b a0 a8 00 00 00 31 c0 <49> 8b 94 24 40 01 00 00 48 83 7a 48 00 0f 84 ee 00 00 00 4c 89 e7
[    3.446386] RSP: 0000:ffffa4d400d73d60 EFLAGS: 00010246
[    3.448133] RAX: 0000000000000000 RBX: ffff9baba677f8a8 RCX: 0000000000000000
[    3.449868] RDX: ffffffffc0301000 RSI: 0000000000000001 RDI: ffff9baba677f8a8
[    3.451637] RBP: 0000000000000000 R08: 00000000000007d0 R09: ffffa4d400d73df0
[    3.453396] R10: 0000000000000001 R11: fefefefefefefeff R12: 0000000000000000
[    3.455148] R13: ffff9baba677f800 R14: 0000000000000000 R15: 0000000000000000
[    3.456885] FS:  0000000000000000(0000) GS:ffff9baba8100000(0000) knlGS:0000000000000000
[    3.458683] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    3.460428] CR2: 0000000000000140 CR3: 00000001ec60a005 CR4: 0000000000760ee0
[    3.462165] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[    3.463933] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[    3.465689] PKRU: 55555554
[    3.473578] sdhci-pci 0000:00:14.5: SDHCI controller found [8086:34f8] (rev 0)
[    3.480245] intel-lpss 0000:00:19.0: enabling device (0000 -> 0002)
[    3.482308] ------------[ cut here ]------------

Activity

  1. plbossart commented on Jan 3, 2019

    @plbossart
    Member

    can you elaborate on the flow, I don't see where we miss a return status when the probe fails?
    sof_probe, snd_create_platform_device all check for the return values. Or maybe the tests we do are incorrect, I assumed we need to do if (IS_ERR(priv->pdev_pcm)) but maybe it's if (IS_ERR_OR_NULL(priv->pdev_pcm)) {

  2. bardliao commented on Jan 4, 2019

    @bardliao
    CollaboratorAuthor

    @plbossart I checked the flow which is sof_create_platform_device() -> ... -> device_add() -> bus_probe_device() Unfortunately, bus_probe_device() is a void function. It will not return error when device porbe failed. And both IS_ERR_OR_NULL(priv->pdev_pcm) and IS_ERR(priv->pdev_pcm) are 0.

  3. keyonjie commented on Jan 4, 2019

    @keyonjie

    can we just add NULL check to PM ops to fix issue?

    sof_suspend() {
    ...
    if (!priv || !sdev)
         /*no sof device created, do nothing */
        retrun 0;
    ...
    }
    ...
    sof_resume() {
    ...
    if (!priv || !sdev)
         /*no sof device created, do nothing */
        retrun 0;
    ...
    }
    

    This means our PCI/ACPI drivers can still run independently, even you unload other sof modules.

  4. plbossart commented on Jan 4, 2019

    @plbossart
    Member

    @bardliao can you share the detailed flow?
    My quick check shows there's always a status, and we've never had any problems with platform_device_register_data.

    platform_device_register_data()
    https://elixir.bootlin.com/linux/latest/source/include/linux/platform_device.h#L161
    
    platform_device_add()
    https://elixir.bootlin.com/linux/latest/source/drivers/base/platform.c#L549
    
    device_add()
    https://elixir.bootlin.com/linux/latest/source/drivers/base/platform.c#L417
    
  5. bardliao commented on Jan 6, 2019

    @bardliao
    CollaboratorAuthor

    @keyonjie Yes, it's an alternative. @plbossart You are right.

    bus_probe_device()
    https://elixir.bootlin.com/linux/latest/source/drivers/base/core.c#L1927
    

    Maybe we need to think an alternative way to fix this issue.

  6. mengdonglin commented on Jan 15, 2019

    @mengdonglin

    @libinyang Is #510 a fix for this?

  7. plbossart commented on Jan 15, 2019

    @plbossart
    Member

    The fix is more likely a change in the way PM routines are used. I am not happy with the work-around suggested, we should fix PM handling instead. Talking with Ranjani on this.

  8. plbossart commented on Jan 25, 2019

    @plbossart
    Member

    duplicate of #505, closing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions