Re: [BUG] KASAN: slab-use-after-free Write in sk_skb_reason_drop
From: Jiayuan Chen
Date: Thu Apr 23 2026 - 10:34:58 EST
On 4/23/26 9:41 PM, Eulgyu Kim wrote:
Hello,
We encountered a "KASAN: slab-use-after-free Write in sk_skb_reason_drop"
on kernel version v7.0.
As this memory corruption bug seems to require `CAP_NET_ADMIN`,
we report this in public mailing list.
We have included the following items below:
- C reproducer (~100 lines)
- kernel delay patch
- KASAN crash log
To reliably trigger the race condition bug, we patched the kernel
to inject a delay at a specific point.
The kernel config used is the same as the syzbot configuration.
Unfortunately, we do not have a fix ready for this bug yet.
As this issue was identified via fuzzing and we have limited background,
we find it challenging to propose a correct fix or evaluate
its potential severity.
We hope this report helps address the issue. Please let us know
if any further information is needed.
Thank you.
Best Regards,
Eulgyu Kim
kernel delay patch:
==================================================================
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index c492fda6f..ba7078e18 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1891,6 +1891,10 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
!tfile->detached)
rxhash = __skb_get_hash_symmetric(skb);
+ if (strcmp(current->comm, "slowme") == 0) {
+ mdelay(2000);
+ }
+
rcu_read_lock();
if (unlikely(!(tun->dev->flags & IFF_UP))) {
err = -EIO;
==================================================================
Hi Eulgyu,
I think this is caused by the lack of napi_mutex protection, and the queue detach path seems to have the same issue.
The fix could be this:
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index b183189f1853..6a0bbd4def76 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -289,8 +289,12 @@ static void tun_napi_disable(struct tun_file *tfile)
static void tun_napi_del(struct tun_file *tfile)
{
- if (tfile->napi_enabled)
- netif_napi_del(&tfile->napi);
+ if (!tfile->napi_enabled)
+ return;
+
+ mutex_lock(&tfile->napi_mutex);
+ netif_napi_del(&tfile->napi);
+ mutex_unlock(&tfile->napi_mutex);
}
static bool tun_napi_frags_enabled(const struct tun_file *tfile)
@@ -1783,6 +1787,12 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
if (frags) {
mutex_lock(&tfile->napi_mutex);
+ if (unlikely(tfile->detached ||
+ rcu_access_pointer(tfile->tun) != tun)) {
+ err = -EBUSY;
+ mutex_unlock(&tfile->napi_mutex);
+ goto out;
+ }
skb = tun_napi_alloc_frags(tfile, copylen, from);
/* tun_napi_alloc_frags() enforces a layout for the skb.
* If zerocopy is enabled, then this layout will be
@@ -1981,6 +1991,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
mutex_unlock(&tfile->napi_mutex);
}
+out:
return err ?: total_len;
}