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 --- net/wireless/tests/util.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 net/wireless/tests/util.c (limited to 'net/wireless/tests/util.c') diff --git a/net/wireless/tests/util.c b/net/wireless/tests/util.c new file mode 100644 index 000000000..118f7fb42 --- /dev/null +++ b/net/wireless/tests/util.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * KUnit fixture to have a (configurable) wiphy + * + * Copyright (C) 2023 Intel Corporation + */ +#include +#include +#include +#include +#include "util.h" + +int t_wiphy_init(struct kunit_resource *resource, void *ctx) +{ + struct kunit *test = kunit_get_current_test(); + struct cfg80211_ops *ops; + struct wiphy *wiphy; + struct t_wiphy_priv *priv; + + ops = kzalloc_obj(*ops); + KUNIT_ASSERT_NOT_NULL(test, ops); + + wiphy = wiphy_new_nm(ops, sizeof(*priv), "kunit"); + KUNIT_ASSERT_NOT_NULL(test, wiphy); + + priv = wiphy_priv(wiphy); + priv->ctx = ctx; + priv->ops = ops; + + /* Initialize channels, feel free to add more here channels/bands */ + memcpy(priv->channels_2ghz, channels_2ghz, sizeof(channels_2ghz)); + wiphy->bands[NL80211_BAND_2GHZ] = &priv->band_2ghz; + priv->band_2ghz.channels = priv->channels_2ghz; + priv->band_2ghz.n_channels = ARRAY_SIZE(channels_2ghz); + + resource->data = wiphy; + resource->name = "wiphy"; + + return 0; +} + +void t_wiphy_exit(struct kunit_resource *resource) +{ + struct t_wiphy_priv *priv; + struct cfg80211_ops *ops; + + priv = wiphy_priv(resource->data); + ops = priv->ops; + + /* Should we ensure anything about the state here? + * e.g. full destruction or no calls to any ops on destruction? + */ + + wiphy_free(resource->data); + kfree(ops); +} -- cgit v1.3.1