/* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifndef _DT_BINDINGS_CLK_APQ_MMCC_8084_H #define _DT_BINDINGS_CLK_APQ_MMCC_8084_H #define MMSS_AHB_CLK_SRC 0 #define MMSS_AXI_CLK_SRC 1 #define MMPLL0 2 #define MMPLL0_VOTE 3 #define MMPLL1 4 #define MMPLL1_VOTE 5 #define MMPLL2 6 #define MMPLL3 7 #define MMPLL4 8 #define CSI0_CLK_SRC 9 #define CSI1_CLK_SRC 10 #define CSI2_CLK_SRC 11 #define CSI3_CLK_SRC 12 #define VCODEC0_CLK_SRC 13 #define VFE0_CLK_SRC 14 #define VFE1_CLK_SRC 15 #define MDP_CLK_SRC 16 #define PCLK0_CLK_SRC 17 #define PCLK1_CLK_SRC 18 #define OCMEMNOC_CLK_SRC 19 #define GFX3D_CLK_SRC 20 #define JPEG0_CLK_SRC 21 #define JPEG1_CLK_SRC 22 #define JPEG2_CLK_SRC 23 #define EDPPIXEL_CLK_SRC 24 #define EXTPCLK_CLK_SRC 25 #define VP_CLK_SRC 26 #define CCI_CLK_SRC 27 #define CAMSS_GP0_CLK_SRC 28 #define CAMSS_GP1_CLK_SRC 29 #define MCLK0_CLK_SRC 30 #define MCLK1_CLK_SRC 31 #define MCLK2_CLK_SRC 32 #define MCLK3_CLK_SRC 33 #define CSI0PHYTIMER_CLK_SRC 34 #define CSI1PHYTIMER_CLK_SRC 35 #define CSI2PHYTIMER_CLK_SRC 36 #define CPP_CLK_SRC 37 #define BYTE0_CLK_SRC 38 #define BYTE1_CLK_SRC 39 #define EDPAUX_CLK_SRC 40 #define EDPLINK_CLK_SRC 41 #define ESC0_CLK_SRC 42 #define ESC1_CLK_SRC 43 #define HDMI_CLK_SRC 44 #define VSYNC_CLK_SRC 45 #define MMSS_RBCPR_CLK_SRC 46 #define RBBMTIMER_CLK_SRC 47 #define MAPLE_CLK_SRC 48 #define VDP_CLK_SRC 49 #define VPU_BUS_CLK_SRC 50 #define MMSS_CXO_CLK 51 #define MMSS_SLEEPCLK_CLK 52 #define AVSYNC_AHB_CLK 53 #define AVSYNC_EDPPIXEL_CLK 54 #define AVSYNC_EXTPCLK_CLK 55 #define AVSYNC_PCLK0_CLK 56 #define AVSYNC_PCLK1_CLK 57 #define AVSYNC_VP_CLK 58 #define CAMSS_AHB_CLK 59 #define CAMSS_CCI_CCI_AHB_CLK 60 #define CAMSS_CCI_CCI_CLK 61 #define CAMSS_CSI0_AHB_CLK 62 #define CAMSS_CSI0_CLK 63 #define CAMSS_CSI0PHY_CLK 64 #define CAMSS_CSI0PIX_CLK 65 #define CAMSS_CSI0RDI_CLK 66 #define CAMSS_CSI1_AHB_CLK 67 #define CAMSS_CSI1_CLK 68 #define CAMSS_CSI1PHY_CLK 69 #define CAMSS_CSI1PIX_CLK 70 #define CAMSS_CSI1RDI_CLK 71 #define CAMSS_CSI2_AHB_CLK 72 #define CAMSS_CSI2_CLK 73 #define CAMSS_CSI2PHY_CLK 74 #define CAMSS_CSI2PIX_CLK 75 #define CAMSS_CSI2RDI_CLK 76 #define CAMSS_CSI3_AHB_CLK 77 #define CAMSS_CSI3_CLK 78 #define CAMSS_CSI3PHY_CLK 79 #define CAMSS_CSI3PIX_CLK 80 #define CAMSS_CSI3RDI_CLK 81 #define CAMSS_CSI_VFE0_CLK 82 #define CAMSS_CSI_VFE1_CLK 83 #define CAMSS_GP0_CLK 84 #define CAMSS_GP1_CLK 85 #define CAMSS_ISPIF_AHB_CLK 86 #define CAMSS_JPEG_JPEG0_CLK 87 #define CAMSS_JPEG_JPEG1_CLK 88 #define CAMSS_JPEG_JPEG2_CLK 89 #define CAMSS_JPEG_JPEG_AHB_CLK 90 #define CAMSS_JPEG_JPEG_AXI_CLK 91 #define CAMSS_MCLK0_CLK 92 #define CAMSS_MCLK1_CLK 93 #define CAMSS_MCLK2_CLK 94 #define CAMSS_MCLK3_CLK 95 #define CAMSS_MICRO_AHB_CLK 96 #define CAMSS_PHY0_CSI0PHYTIMER_CLK 97 #define CAMSS_PHY1_CSI1PHYTIMER_CLK 98 #define CAMSS_PHY2_CSI2PHYTIMER_CLK 99 #define CAMSS_TOP_AHB_CLK 100 #define CAMSS_VFE_CPP_AHB_CLK 101 #define CAMSS_VFE_CPP_CLK 102 #define CAMSS_VFE_VFE0_CLK 103 #define CAMSS_VFE_VFE1_CLK 104 #define CAMSS_VFE_VFE_AHB_CLK 105 #define CAMSS_VFE_VFE_AXI_CLK 106 #define MDSS_AHB_CLK 107 #define MDSS_AXI_CLK 108 #define MDSS_BYTE0_CLK 109 #define MDSS_BYTE1_CLK 110 #define MDSS_EDPAUX_CLK 111 #define MDSS_EDPLINK_CLK 112 #define MDSS_EDPPIXEL_CLK 113 #define MDSS_ESC0_CLK 114 #define MDSS_ESC1_CLK 115 #define MDSS_EXTPCLK_CLK 116 #define MDSS_HDMI_AHB_CLK 117 #define MDSS_HDMI_CLK 118 #define MDSS_MDP_CLK 119 #define MDSS_MDP_LUT_CLK 120 #define MDSS_PCLK0_CLK 121 #define MDSS_PCLK1_CLK 122 #define MDSS_VSYNC_CLK 123 #define MMSS_RBCPR_AHB_CLK 124 #define MMSS_RBCPR_CLK 125 #define MMSS_SPDM_AHB_CLK 126 #define MMSS_SPDM_AXI_CLK 127 #define MMSS_SPDM_CSI0_CLK 128 #define MMSS_SPDM_GFX3D_CLK 129 #define MMSS_SPDM_JPEG0_CLK 130 #define MMSS_SPDM_JPEG1_CLK 131 #define MMSS_SPDM_JPEG2_CLK 132 #define MMSS_SPDM_MDP_CLK 133 #define MMSS_SPDM_PCLK0_CLK 134 #define MMSS_SPDM_PCLK1_CLK 135 #define MMSS_SPDM_VCODEC0_CLK 136 #define MMSS_SPDM_VFE0_CLK 137 #define MMSS_SPDM_VFE1_CLK 138 #define MMSS_SPDM_RM_AXI_CLK 139 #define MMSS_SPDM_RM_OCMEMNOC_CLK 140 #define MMSS_MISC_AHB_CLK 141 #define MMSS_MMSSNOC_AHB_CLK 142 #define MMSS_MMSSNOC_BTO_AHB_CLK 143 #define MMSS_MMSSNOC_AXI_CLK 144 #define MMSS_S0_AXI_CLK 145 #define OCMEMCX_AHB_CLK 146 #define OCMEMCX_OCMEMNOC_CLK 147 #define OXILI_OCMEMGX_CLK 148 #define OXILI_GFX3D_CLK 149 #define OXILI_RBBMTIMER_CLK 150 #define OXILICX_AHB_CLK 151 #define VENUS0_AHB_CLK 152 #define VENUS0_AXI_CLK 153 #define VENUS0_CORE0_VCODEC_CLK 154 #define VENUS0_CORE1_VCODEC_CLK 155 #define VENUS0_OCMEMNOC_CLK 156 #define VENUS0_VCODEC0_CLK 157 #define VPU_AHB_CLK 158 #define VPU_AXI_CLK 159 #define VPU_BUS_CLK 160 #define VPU_CXO_CLK 161 #define VPU_MAPLE_CLK 162 #define VPU_SLEEP_CLK 163 #define VPU_VDP_CLK 164 /* GDSCs */ #define VENUS0_GDSC 0 #define VENUS0_CORE0_GDSC 1 #define VENUS0_CORE1_GDSC 2 #define MDSS_GDSC 3 #define CAMSS_JPEG_GDSC 4 #define CAMSS_VFE_GDSC 5 #define OXILI_GDSC 6 #define OXILICX_GDSC 7 #endif ck.c?id=49def1853334396f948dcb4cedb9347abb318df5'>49def1853334396f948dcb4cedb9347abb318df5 (diff)
firmware: fix NULL pointer dereference in __fw_load_abort()
Since commit 5d47ec02c37ea6 ("firmware: Correct handling of fw_state_wait() return value") fw_load_abort() could be called twice and lead us to a kernel crash. This happens only when the firmware fallback mechanism (regular or custom) is used. The fallback mechanism exposes a sysfs interface for userspace to upload a file and notify the kernel when the file is loaded and ready, or to cancel an upload by echo'ing -1 into on the loading file: echo -n "-1" > /sys/$DEVPATH/loading This will call fw_load_abort(). Some distributions actually have a udev rule in place to *always* immediately cancel all firmware fallback mechanism requests (Debian), they have: $ cat /lib/udev/rules.d/50-firmware.rules # stub for immediately telling the kernel that userspace firmware loading # failed; necessary to avoid long timeouts with CONFIG_FW_LOADER_USER_HELPER=y SUBSYSTEM=="firmware", ACTION=="add", ATTR{loading}="-1 Distributions with this udev rule would run into this crash only if the fallback mechanism is used. Since most distributions disable by default using the fallback mechanism (CONFIG_FW_LOADER_USER_HELPER_FALLBACK), this would typicaly mean only 2 drivers which *require* the fallback mechanism could typically incur a crash: drivers/firmware/dell_rbu.c and the drivers/leds/leds-lp55xx-common.c driver. Distributions enabling CONFIG_FW_LOADER_USER_HELPER_FALLBACK by default are obviously more exposed to this crash. The crash happens because after commit 5b029624948d ("firmware: do not use fw_lock for fw_state protection") and subsequent fix commit 5d47ec02c37ea6 ("firmware: Correct handling of fw_state_wait() return value") a race can happen between this cancelation and the firmware fw_state_wait_timeout() being woken up after a state change with which fw_load_abort() as that calls swake_up(). Upon error fw_state_wait_timeout() will also again call fw_load_abort() and trigger a null reference. At first glance we could just fix this with a !buf check on fw_load_abort() before accessing buf->fw_st, however there is a logical issue in having a state machine used for the fallback mechanism and preventing access from it once we abort as its inside the buf (buf->fw_st). The firmware_class.c code is setting the buf to NULL to annotate an abort has occurred. Replace this mechanism by simply using the state check instead. All the other code in place already uses similar checks for aborting as well so no further changes are needed. An oops can be reproduced with the new fw_fallback.sh fallback mechanism cancellation test. Either cancelling the fallback mechanism or the custom fallback mechanism triggers a crash. mcgrof@piggy ~/linux-next/tools/testing/selftests/firmware (git::20170111-fw-fixes)$ sudo ./fw_fallback.sh ./fw_fallback.sh: timeout works ./fw_fallback.sh: firmware comparison works ./fw_fallback.sh: fallback mechanism works [ this then sits here when it is trying the cancellation test ] Kernel log: test_firmware: loading 'nope-test-firmware.bin' misc test_firmware: Direct firmware load for nope-test-firmware.bin failed with error -2 misc test_firmware: Falling back to user helper BUG: unable to handle kernel NULL pointer dereference at 0000000000000038 IP: _request_firmware+0xa27/0xad0 PGD 0 Oops: 0000 [#1] SMP Modules linked in: test_firmware(E) ... etc ... CPU: 1 PID: 1396 Comm: fw_fallback.sh Tainted: G W E 4.10.0-rc3-next-20170111+ #30 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.10.1-0-g8891697-prebuilt.qemu-project.org 04/01/2014 task: ffff9740b27f4340 task.stack: ffffbb15c0bc8000 RIP: 0010:_request_firmware+0xa27/0xad0 RSP: 0018:ffffbb15c0bcbd10 EFLAGS: 00010246 RAX: 00000000fffffffe RBX: ffff9740afe5aa80 RCX: 0000000000000000 RDX: ffff9740b27f4340 RSI: 0000000000000283 RDI: 0000000000000000 RBP: ffffbb15c0bcbd90 R08: ffffbb15c0bcbcd8 R09: 0000000000000000 R10: 0000000894a0d4b1 R11: 000000000000008c R12: ffffffffc0312480 R13: 0000000000000005 R14: ffff9740b1c32400 R15: 00000000000003e8 FS: 00007f8604422700(0000) GS:ffff9740bfc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000038 CR3: 000000012164c000 CR4: 00000000000006e0 Call Trace: request_firmware+0x37/0x50 trigger_request_store+0x79/0xd0 [test_firmware] dev_attr_store+0x18/0x30 sysfs_kf_write+0x37/0x40 kernfs_fop_write+0x110/0x1a0 __vfs_write+0x37/0x160 ? _cond_resched+0x1a/0x50 vfs_write+0xb5/0x1a0 SyS_write+0x55/0xc0 ? trace_do_page_fault+0x37/0xd0 entry_SYSCALL_64_fastpath+0x1e/0xad RIP: 0033:0x7f8603f49620 RSP: 002b:00007fff6287b788 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 000055c307b110a0 RCX: 00007f8603f49620 RDX: 0000000000000016 RSI: 000055c3084d8a90 RDI: 0000000000000001 RBP: 0000000000000016 R08: 000000000000c0ff R09: 000055c3084d6336 R10: 000055c307b108b0 R11: 0000000000000246 R12: 000055c307b13c80 R13: 000055c3084d6320 R14: 0000000000000000 R15: 00007fff6287b950 Code: 9f 64 84 e8 9c 61 fe ff b8 f4 ff ff ff e9 6b f9 ff ff 48 c7 c7 40 6b 8d 84 89 45 a8 e8 43 84 18 00 49 8b be 00 03 00 00 8b 45 a8 <83> 7f 38 02 74 08 e8 6e ec ff ff 8b 45 a8 49 c7 86 00 03 00 00 RIP: _request_firmware+0xa27/0xad0 RSP: ffffbb15c0bcbd10 CR2: 0000000000000038 ---[ end trace 6d94ac339c133e6f ]--- Fixes: 5d47ec02c37e ("firmware: Correct handling of fw_state_wait() return value") Reported-and-Tested-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reported-and-Tested-by: Patrick Bruenn <p.bruenn@beckhoff.com> Reported-by: Chris Wilson <chris@chris-wilson.co.uk> CC: <stable@vger.kernel.org> [3.10+] Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'sound/core/seq/seq_lock.c')