From e873c74132f0c5f1452816cd9bb26208f0bba1e1 Mon Sep 17 00:00:00 2001 From: Shivank Garg Date: Sat, 22 Aug 2026 19:22:05 +0000 Subject: dmaengine: fix use-after-free in dma_chan_put() and dma_release_channel() When dma_device_put() drops the last reference on chan->device->ref, dma_device_release() runs and may free the dma_device along with its channels. dma_chan_put() then still reads chan->device->owner via dma_chan_to_owner() for the trailing module_put(). KASAN catches it: slab-use-after-free in dma_chan_put+0x3e6/0x4c0 Read of size 8 by task insmod/6319 Freed by task 6319: kfree+0x225/0x470 dma_chan_put+0x395/0x4c0 dmaengine_put+0xf8/0x160 Cache the module owner in dma_chan_put() before the put so the trailing module_put() does not need chan->device. Fixes: 8ad342a86359 ("dmaengine: Add reference counting to dma_device struct") Suggested-by: Sashiko Link: https://sashiko.dev/#/patchset/20260518-dmaengine-kref-fix-v1-1-4d6125048fb7@amd.com Reviewed-by: Frank Li Reviewed-by: Logan Gunthorpe Signed-off-by: Shivank Garg Link: https://patch.msgid.link/20260822-dmaengine-kref-fix-v5-3-d4a4ee47d927@amd.com Signed-off-by: Vinod Koul --- include/trace/events/siox.h | 66 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 include/trace/events/siox.h (limited to 'include/trace/events/siox.h') diff --git a/include/trace/events/siox.h b/include/trace/events/siox.h new file mode 100644 index 000000000..68a43fc2c --- /dev/null +++ b/include/trace/events/siox.h @@ -0,0 +1,66 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM siox + +#if !defined(_TRACE_SIOX_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SIOX_H + +#include + +TRACE_EVENT(siox_set_data, + TP_PROTO(const struct siox_master *smaster, + const struct siox_device *sdevice, + unsigned int devno, size_t bufoffset), + TP_ARGS(smaster, sdevice, devno, bufoffset), + TP_STRUCT__entry( + __field(int, busno) + __field(unsigned int, devno) + __field(size_t, inbytes) + __dynamic_array(u8, buf, sdevice->inbytes) + ), + TP_fast_assign( + __entry->busno = smaster->busno; + __entry->devno = devno; + __entry->inbytes = sdevice->inbytes; + memcpy(__get_dynamic_array(buf), + smaster->buf + bufoffset, sdevice->inbytes); + ), + TP_printk("siox-%d-%u [%*phD]", + __entry->busno, + __entry->devno, + (int)__entry->inbytes, __get_dynamic_array(buf) + ) +); + +TRACE_EVENT(siox_get_data, + TP_PROTO(const struct siox_master *smaster, + const struct siox_device *sdevice, + unsigned int devno, u8 status_clean, + size_t bufoffset), + TP_ARGS(smaster, sdevice, devno, status_clean, bufoffset), + TP_STRUCT__entry( + __field(int, busno) + __field(unsigned int, devno) + __field(u8, status_clean) + __field(size_t, outbytes) + __dynamic_array(u8, buf, sdevice->outbytes) + ), + TP_fast_assign( + __entry->busno = smaster->busno; + __entry->devno = devno; + __entry->status_clean = status_clean; + __entry->outbytes = sdevice->outbytes; + memcpy(__get_dynamic_array(buf), + smaster->buf + bufoffset, sdevice->outbytes); + ), + TP_printk("siox-%d-%u (%02hhx) [%*phD]", + __entry->busno, + __entry->devno, + __entry->status_clean, + (int)__entry->outbytes, __get_dynamic_array(buf) + ) +); + +#endif /* if !defined(_TRACE_SIOX_H) || defined(TRACE_HEADER_MULTI_READ) */ + +/* This part must be outside protection */ +#include -- cgit v1.3.1