summaryrefslogtreecommitdiff
path: root/drivers/hwtracing
diff options
context:
space:
mode:
authorJunrui Luo <moonafterrain@outlook.com>2026-06-04 15:34:25 +0800
committerSuzuki K Poulose <suzuki.poulose@arm.com>2026-06-04 09:56:13 +0100
commit98495b5a4d77dd22e106f462b76e1093a55b29a7 (patch)
tree6f412eb3620bf13cb7d70621c9d0f4a5112e3d59 /drivers/hwtracing
parentfa09f08ede3db3050ae16ae1ed92c902d0cada23 (diff)
downloadlinux-next-98495b5a4d77dd22e106f462b76e1093a55b29a7.tar.gz
linux-next-98495b5a4d77dd22e106f462b76e1093a55b29a7.zip
coresight: ultrasoc-smb: Fix OOB write in smb_sync_perf_buffer()
When the SMB sink is used as a perf AUX sink, smb_update_buffer() calls smb_sync_perf_buffer() to copy hardware trace data into the perf AUX ring buffer pages. It derives pg_idx = head >> PAGE_SHIFT from @head, which is handle->head, and indexes dst_pages[pg_idx]. The pg_idx %= nr_pages normalization is only applied after the first loop iteration. This leaves the initial page index underived from the buffer size, which can result in an out-of-bounds write past dst_pages[] when head exceeds the AUX buffer size. Normalize head modulo the AUX buffer size before deriving the page index and offset, mirroring tmc_etr_sync_perf_buffer(). Fixes: 06f5c2926aaa ("drivers/coresight: Add UltraSoc System Memory Buffer driver") Reported-by: Yuhao Jiang <danisjiang@gmail.com> Cc: stable@vger.kernel.org Signed-off-by: Junrui Luo <moonafterrain@outlook.com> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/SYBPR01MB788156B3380A36835DB22290AF102@SYBPR01MB7881.ausprd01.prod.outlook.com
Diffstat (limited to 'drivers/hwtracing')
-rw-r--r--drivers/hwtracing/coresight/ultrasoc-smb.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c
index 5776f63468fa..20a950b9dd4f 100644
--- a/drivers/hwtracing/coresight/ultrasoc-smb.c
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.c
@@ -337,6 +337,7 @@ static void smb_sync_perf_buffer(struct smb_drv_data *drvdata,
unsigned long to_copy;
long pg_idx, pg_offset;
+ head %= (unsigned long)buf->nr_pages << PAGE_SHIFT;
pg_idx = head >> PAGE_SHIFT;
pg_offset = head & (PAGE_SIZE - 1);