[PATCH 1/4] coresight: tmc: Don't reallocate the sysfs_buffer if it's in use
Yicong Yang
yangyicong at huawei.com
Mon Dec 2 01:24:16 PST 2024
From: Suzuki K Poulose <suzuki.poulose at arm.com>
Enable the trace in below steps will crash the kernel by NULL pointer
dereferencing:
echo 1 > /sys/bus/coresight/devices/tmc_etr0/enable_sink
echo 1 > /sys/bus/coresight/devices/etm0/enable_source
echo 0x400000 > /sys/bus/coresight/devices/tmc_etr0/buffer_size
echo 1 > /sys/bus/coresight/devices/etm2/enable_source
dd if=/dev/tmc_etr0 of=test_etm_sysfs_etr_030.data
The call trace will be like:
WARNING: CPU: 39 PID: 8586 at drivers/hwtracing/coresight/coresight-tmc-etr.c:1123 __tmc_etr_disable_hw+0x108/0x140 [coresight_tmc]
[...]
Call trace:
__tmc_etr_disable_hw+0x108/0x140 [coresight_tmc]
tmc_read_prepare_etr+0xc0/0xd0 [coresight_tmc]
tmc_open+0x60/0xa0 [coresight_tmc]
misc_open+0x11c/0x170
chrdev_open+0xcc/0x2b0
do_dentry_open+0x140/0x4e0
vfs_open+0x34/0xf8
path_openat+0x2b0/0xf58
do_filp_open+0x8c/0x148
do_sys_openat2+0xb8/0xe8
__arm64_sys_openat+0x70/0xc0
el0_svc_common.constprop.0+0x64/0x148
do_el0_svc+0x24/0x38
el0_svc+0x40/0x140
el0t_64_sync_handler+0xc0/0xc8
el0t_64_sync+0x1a4/0x1a8
---[ end trace 0000000000000000 ]---
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000028
[...]
Call trace:
tmc_etr_get_sysfs_trace+0x10/0x80 [coresight_tmc]
vfs_read+0xcc/0x310
ksys_read+0x74/0x108
__arm64_sys_read+0x24/0x38
el0_svc_common.constprop.0+0x64/0x148
do_el0_svc+0x24/0x38
el0_svc+0x40/0x140
Due to the buffer size changed, the buffer will be reallocated in
tmc_etr_get_sysfs_buffer() when the second source enabled. At trace
end tmc_etr_sync_sysfs_buf() will reset the drvdata->sysfs_buf and
trigger the later NULL pointer dereference when reading out the
data. Fix this by checking whether the buffer's in use before
reallocate a now one in tmc_etr_get_sysfs_buffer().
Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
drivers/hwtracing/coresight/coresight-tmc-etr.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index a48bb85d0e7f..ad83714ca4dc 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1178,7 +1178,11 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev)
*/
spin_lock_irqsave(&drvdata->spinlock, flags);
sysfs_buf = READ_ONCE(drvdata->sysfs_buf);
- if (!sysfs_buf || (sysfs_buf->size != drvdata->size)) {
+
+ /* Don't reallocate the buffer if it's already in use */
+ if (!sysfs_buf ||
+ ((sysfs_buf->size != drvdata->size) &&
+ coresight_get_mode(csdev) != CS_MODE_SYSFS)) {
spin_unlock_irqrestore(&drvdata->spinlock, flags);
/* Allocate memory with the locks released */
--
2.24.0
More information about the linux-arm-kernel
mailing list