drivers/net/ppp/ppp_generic.c | 107 +++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 46 deletions(-)
Currently, ppp->xmit_pending is used in ppp_send_frame() to pass a skb
to ppp_push(), and holds the skb when a PPP channel cannot immediately
transmit it. This state is redundant because the transmit queue
(ppp->file.xq) can already handle the backlog. Furthermore, during
normal operation, an skb is queued in file.xq only to be immediately
dequeued, causing unnecessary overhead.
Refactor the transmit path to avoid stashing the skb when possible:
- Remove ppp->xmit_pending.
- Rename ppp_send_frame() to ppp_prepare_tx_skb(), and don't call
ppp_push() in it. It returns 1 if the skb is consumed
(dropped/handled) or 0 if it can be passed to ppp_push().
- Update ppp_push() to accept the skb. It returns 1 if the skb is
consumed, or 0 if the channel is busy.
- Optimize __ppp_xmit_process():
- Fastpath: If the queue is empty, attempt to send the skb directly
via ppp_push(). If busy, queue it.
- Slowpath: If the queue is not empty, or fastpath failed, process
the backlog in file.xq. Split dequeueing loop into a separate
function ppp_xmit_flush() so ppp_channel_push() uses that directly
instead of passing a NULL skb to __ppp_xmit_process().
This simplifies the states and reduces locking in the fastpath.
Signed-off-by: Qingfang Deng <dqfext@gmail.com>
---
- Sent as RFC, since net-next is closed.
drivers/net/ppp/ppp_generic.c | 107 +++++++++++++++++++---------------
1 file changed, 61 insertions(+), 46 deletions(-)
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index f8814d7be6f1..0f7bc3ab4a49 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -134,7 +134,6 @@ struct ppp {
int debug; /* debug flags 70 */
struct slcompress *vj; /* state for VJ header compression */
enum NPmode npmode[NUM_NP]; /* what to do with each net proto 78 */
- struct sk_buff *xmit_pending; /* a packet ready to go out 88 */
struct compressor *xcomp; /* transmit packet compressor 8c */
void *xc_state; /* its internal state 90 */
struct compressor *rcomp; /* receive decompressor 94 */
@@ -264,8 +263,8 @@ struct ppp_net {
static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
struct file *file, unsigned int cmd, unsigned long arg);
static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb);
-static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);
-static void ppp_push(struct ppp *ppp);
+static int ppp_prepare_tx_skb(struct ppp *ppp, struct sk_buff *skb);
+static int ppp_push(struct ppp *ppp, struct sk_buff *skb);
static void ppp_channel_push(struct channel *pch);
static void ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb,
struct channel *pch);
@@ -1651,26 +1650,44 @@ static void ppp_setup(struct net_device *dev)
*/
/* Called to do any work queued up on the transmit side that can now be done */
+static void ppp_xmit_flush(struct ppp *ppp)
+{
+ struct sk_buff *skb;
+
+ while ((skb = skb_dequeue(&ppp->file.xq))) {
+ if (unlikely(!ppp_push(ppp, skb))) {
+ skb_queue_head(&ppp->file.xq, skb);
+ return;
+ }
+ }
+ /* If there's no work left to do, tell the core net code that we can
+ * accept some more.
+ */
+ netif_wake_queue(ppp->dev);
+}
+
static void __ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb)
{
ppp_xmit_lock(ppp);
- if (!ppp->closing) {
- ppp_push(ppp);
-
- if (skb)
+ if (unlikely(ppp->closing)) {
+ kfree_skb(skb);
+ goto out;
+ }
+ if (unlikely(ppp_prepare_tx_skb(ppp, skb)))
+ goto out;
+ /* Fastpath: No backlog, just send the new skb. */
+ if (likely(skb_queue_empty(&ppp->file.xq))) {
+ if (unlikely(!ppp_push(ppp, skb))) {
skb_queue_tail(&ppp->file.xq, skb);
- while (!ppp->xmit_pending &&
- (skb = skb_dequeue(&ppp->file.xq)))
- ppp_send_frame(ppp, skb);
- /* If there's no work left to do, tell the core net
- code that we can accept some more. */
- if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq))
- netif_wake_queue(ppp->dev);
- else
netif_stop_queue(ppp->dev);
- } else {
- kfree_skb(skb);
+ }
+ goto out;
}
+
+ /* Slowpath: Enqueue the new skb and process backlog */
+ skb_queue_tail(&ppp->file.xq, skb);
+ ppp_xmit_flush(ppp);
+out:
ppp_xmit_unlock(ppp);
}
@@ -1757,12 +1774,12 @@ pad_compress_skb(struct ppp *ppp, struct sk_buff *skb)
}
/*
- * Compress and send a frame.
- * The caller should have locked the xmit path,
- * and xmit_pending should be 0.
+ * Compress and prepare to send a frame.
+ * The caller should have locked the xmit path.
+ * Returns 1 if the skb was consumed, 0 if it can be passed to ppp_push().
*/
-static void
-ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
+static int
+ppp_prepare_tx_skb(struct ppp *ppp, struct sk_buff *skb)
{
int proto = PPP_PROTO(skb);
struct sk_buff *new_skb;
@@ -1784,7 +1801,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
"PPP: outbound frame "
"not passed\n");
kfree_skb(skb);
- return;
+ return 1;
}
/* if this packet passes the active filter, record the time */
if (!(ppp->active_filter &&
@@ -1869,42 +1886,38 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
goto drop;
skb_queue_tail(&ppp->file.rq, skb);
wake_up_interruptible(&ppp->file.rwait);
- return;
+ return 1;
}
- ppp->xmit_pending = skb;
- ppp_push(ppp);
- return;
+ return 0;
drop:
kfree_skb(skb);
++ppp->dev->stats.tx_errors;
+ return 1;
}
/*
- * Try to send the frame in xmit_pending.
+ * Try to send the frame.
* The caller should have the xmit path locked.
+ * Returns 1 if the skb was consumed, 0 if not.
*/
-static void
-ppp_push(struct ppp *ppp)
+static int
+ppp_push(struct ppp *ppp, struct sk_buff *skb)
{
struct list_head *list;
struct channel *pch;
- struct sk_buff *skb = ppp->xmit_pending;
-
- if (!skb)
- return;
list = &ppp->channels;
if (list_empty(list)) {
/* nowhere to send the packet, just drop it */
- ppp->xmit_pending = NULL;
kfree_skb(skb);
- return;
+ return 1;
}
if ((ppp->flags & SC_MULTILINK) == 0) {
struct ppp_channel *chan;
+ int ret;
/* not doing multilink: send it down the first channel */
list = list->next;
pch = list_entry(list, struct channel, clist);
@@ -1916,27 +1929,26 @@ ppp_push(struct ppp *ppp)
* skb but linearization failed
*/
kfree_skb(skb);
- ppp->xmit_pending = NULL;
+ ret = 1;
goto out;
}
- if (chan->ops->start_xmit(chan, skb))
- ppp->xmit_pending = NULL;
+ ret = chan->ops->start_xmit(chan, skb);
out:
spin_unlock(&pch->downl);
- return;
+ return ret;
}
#ifdef CONFIG_PPP_MULTILINK
/* Multilink: fragment the packet over as many links
as can take the packet at the moment. */
if (!ppp_mp_explode(ppp, skb))
- return;
+ return 0;
#endif /* CONFIG_PPP_MULTILINK */
- ppp->xmit_pending = NULL;
kfree_skb(skb);
+ return 1;
}
#ifdef CONFIG_PPP_MULTILINK
@@ -2005,7 +2017,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
* performance if we have a lot of channels.
*/
if (nfree == 0 || nfree < navail / 2)
- return 0; /* can't take now, leave it in xmit_pending */
+ return 0; /* can't take now, leave it in transmit queue */
/* Do protocol field compression */
if (skb_linearize(skb))
@@ -2199,8 +2211,12 @@ static void __ppp_channel_push(struct channel *pch, struct ppp *ppp)
spin_unlock(&pch->downl);
/* see if there is anything from the attached unit to be sent */
if (skb_queue_empty(&pch->file.xq)) {
- if (ppp)
- __ppp_xmit_process(ppp, NULL);
+ if (ppp) {
+ ppp_xmit_lock(ppp);
+ if (!ppp->closing)
+ ppp_xmit_flush(ppp);
+ ppp_xmit_unlock(ppp);
+ }
}
}
@@ -3460,7 +3476,6 @@ static void ppp_destroy_interface(struct ppp *ppp)
}
#endif /* CONFIG_PPP_FILTER */
- kfree_skb(ppp->xmit_pending);
free_percpu(ppp->xmit_recursion);
free_netdev(ppp->dev);
--
2.43.0
On 09/02/2026 02:11, Qingfang Deng wrote: > Currently, ppp->xmit_pending is used in ppp_send_frame() to pass a skb > to ppp_push(), and holds the skb when a PPP channel cannot immediately > transmit it. This state is redundant because the transmit queue > (ppp->file.xq) can already handle the backlog. Furthermore, during > normal operation, an skb is queued in file.xq only to be immediately > dequeued, causing unnecessary overhead. > > Refactor the transmit path to avoid stashing the skb when possible: > - Remove ppp->xmit_pending. > - Rename ppp_send_frame() to ppp_prepare_tx_skb(), and don't call > ppp_push() in it. It returns 1 if the skb is consumed > (dropped/handled) or 0 if it can be passed to ppp_push(). > - Update ppp_push() to accept the skb. It returns 1 if the skb is > consumed, or 0 if the channel is busy. > - Optimize __ppp_xmit_process(): > - Fastpath: If the queue is empty, attempt to send the skb directly > via ppp_push(). If busy, queue it. > - Slowpath: If the queue is not empty, or fastpath failed, process > the backlog in file.xq. Split dequeueing loop into a separate > function ppp_xmit_flush() so ppp_channel_push() uses that directly > instead of passing a NULL skb to __ppp_xmit_process(). > > This simplifies the states and reduces locking in the fastpath. Quite insteresting optimization. Did you measure the improvements? Like pps over PPP interface, or the length of backlog at some ppp rate?
On Mon, Feb 9, 2026 at 7:17 PM Vadim Fedorenko <vadim.fedorenko@linux.dev> wrote: > On 09/02/2026 02:11, Qingfang Deng wrote: > > Currently, ppp->xmit_pending is used in ppp_send_frame() to pass a skb > > to ppp_push(), and holds the skb when a PPP channel cannot immediately > > transmit it. This state is redundant because the transmit queue > > (ppp->file.xq) can already handle the backlog. Furthermore, during > > normal operation, an skb is queued in file.xq only to be immediately > > dequeued, causing unnecessary overhead. > > > > Refactor the transmit path to avoid stashing the skb when possible: > > - Remove ppp->xmit_pending. > > - Rename ppp_send_frame() to ppp_prepare_tx_skb(), and don't call > > ppp_push() in it. It returns 1 if the skb is consumed > > (dropped/handled) or 0 if it can be passed to ppp_push(). > > - Update ppp_push() to accept the skb. It returns 1 if the skb is > > consumed, or 0 if the channel is busy. > > - Optimize __ppp_xmit_process(): > > - Fastpath: If the queue is empty, attempt to send the skb directly > > via ppp_push(). If busy, queue it. > > - Slowpath: If the queue is not empty, or fastpath failed, process > > the backlog in file.xq. Split dequeueing loop into a separate > > function ppp_xmit_flush() so ppp_channel_push() uses that directly > > instead of passing a NULL skb to __ppp_xmit_process(). > > > > This simplifies the states and reduces locking in the fastpath. > > Quite insteresting optimization. Did you measure the improvements? Like > pps over PPP interface, or the length of backlog at some ppp rate? Not yet. I may test it with PPPoE when I have access to a network traffic generator tomorrow.
syzbot ci has tested the following series
[v1] ppp: don't store tx skb in the fastpath
https://lore.kernel.org/all/20260209021134.21194-1-dqfext@gmail.com
* [RFC PATCH net-next] ppp: don't store tx skb in the fastpath
and found the following issue:
KASAN: slab-use-after-free Write in sk_skb_reason_drop
Full report is available here:
https://ci.syzbot.org/series/0307aa1e-223a-4cd7-af71-1a3c3b7b33f0
***
KASAN: slab-use-after-free Write in sk_skb_reason_drop
tree: net-next
URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/netdev/net-next.git
base: 57be33f85e369ce9f69f61eaa34734e0d3bd47a7
arch: amd64
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
config: https://ci.syzbot.org/builds/3b8a7fc0-258a-4d96-b4cf-cf828112415c/config
C repro: https://ci.syzbot.org/findings/43f9458e-e8a7-4c35-83a9-fd92f2c65af4/c_repro
syz repro: https://ci.syzbot.org/findings/43f9458e-e8a7-4c35-83a9-fd92f2c65af4/syz_repro
==================================================================
BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:96 [inline]
BUG: KASAN: slab-use-after-free in atomic_fetch_sub_release include/linux/atomic/atomic-instrumented.h:400 [inline]
BUG: KASAN: slab-use-after-free in __refcount_sub_and_test include/linux/refcount.h:389 [inline]
BUG: KASAN: slab-use-after-free in __refcount_dec_and_test include/linux/refcount.h:432 [inline]
BUG: KASAN: slab-use-after-free in refcount_dec_and_test include/linux/refcount.h:450 [inline]
BUG: KASAN: slab-use-after-free in skb_unref include/linux/skbuff.h:1292 [inline]
BUG: KASAN: slab-use-after-free in __sk_skb_reason_drop net/core/skbuff.c:1226 [inline]
BUG: KASAN: slab-use-after-free in sk_skb_reason_drop+0x37/0x170 net/core/skbuff.c:1254
Write of size 4 at addr ffff88811262cce4 by task syz.0.17/5962
CPU: 1 UID: 0 PID: 5962 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0xba/0x230 mm/kasan/report.c:482
kasan_report+0x117/0x150 mm/kasan/report.c:595
check_region_inline mm/kasan/generic.c:-1 [inline]
kasan_check_range+0x264/0x2c0 mm/kasan/generic.c:200
instrument_atomic_read_write include/linux/instrumented.h:96 [inline]
atomic_fetch_sub_release include/linux/atomic/atomic-instrumented.h:400 [inline]
__refcount_sub_and_test include/linux/refcount.h:389 [inline]
__refcount_dec_and_test include/linux/refcount.h:432 [inline]
refcount_dec_and_test include/linux/refcount.h:450 [inline]
skb_unref include/linux/skbuff.h:1292 [inline]
__sk_skb_reason_drop net/core/skbuff.c:1226 [inline]
sk_skb_reason_drop+0x37/0x170 net/core/skbuff.c:1254
kfree_skb_reason include/linux/skbuff.h:1322 [inline]
kfree_skb include/linux/skbuff.h:1331 [inline]
ppp_push+0x1284/0x1440 drivers/net/ppp/ppp_generic.c:-1
__ppp_xmit_process drivers/net/ppp/ppp_generic.c:1680 [inline]
ppp_xmit_process+0x9d7/0x1d90 drivers/net/ppp/ppp_generic.c:1706
ppp_write+0x2c6/0x400 drivers/net/ppp/ppp_generic.c:540
do_loop_readv_writev fs/read_write.c:850 [inline]
vfs_writev+0x4bd/0x990 fs/read_write.c:1059
do_pwritev fs/read_write.c:1153 [inline]
__do_sys_pwritev fs/read_write.c:1199 [inline]
__se_sys_pwritev fs/read_write.c:1194 [inline]
__x64_sys_pwritev+0x19f/0x2a0 fs/read_write.c:1194
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f1a1d39acb9
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffc1381da18 EFLAGS: 00000246 ORIG_RAX: 0000000000000128
RAX: ffffffffffffffda RBX: 00007f1a1d615fa0 RCX: 00007f1a1d39acb9
RDX: 0000000000000001 RSI: 00002000000002c0 RDI: 0000000000000003
RBP: 00007f1a1d408bf7 R08: 0000000000000001 R09: 0000000000000000
R10: 0000000000000007 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f1a1d615fac R14: 00007f1a1d615fa0 R15: 00007f1a1d615fa0
</TASK>
Allocated by task 5962:
kasan_save_stack mm/kasan/common.c:57 [inline]
kasan_save_track+0x3e/0x80 mm/kasan/common.c:78
unpoison_slab_object mm/kasan/common.c:340 [inline]
__kasan_slab_alloc+0x6c/0x80 mm/kasan/common.c:366
kasan_slab_alloc include/linux/kasan.h:253 [inline]
slab_post_alloc_hook mm/slub.c:4953 [inline]
slab_alloc_node mm/slub.c:5263 [inline]
kmem_cache_alloc_node_noprof+0x427/0x6f0 mm/slub.c:5315
__alloc_skb+0x1d0/0x7d0 net/core/skbuff.c:702
alloc_skb include/linux/skbuff.h:1383 [inline]
ppp_write+0xb1/0x400 drivers/net/ppp/ppp_generic.c:523
do_loop_readv_writev fs/read_write.c:850 [inline]
vfs_writev+0x4bd/0x990 fs/read_write.c:1059
do_pwritev fs/read_write.c:1153 [inline]
__do_sys_pwritev fs/read_write.c:1199 [inline]
__se_sys_pwritev fs/read_write.c:1194 [inline]
__x64_sys_pwritev+0x19f/0x2a0 fs/read_write.c:1194
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 5962:
kasan_save_stack mm/kasan/common.c:57 [inline]
kasan_save_track+0x3e/0x80 mm/kasan/common.c:78
kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:584
poison_slab_object mm/kasan/common.c:253 [inline]
__kasan_slab_free+0x5c/0x80 mm/kasan/common.c:285
kasan_slab_free include/linux/kasan.h:235 [inline]
slab_free_hook mm/slub.c:2540 [inline]
slab_free mm/slub.c:6674 [inline]
kmem_cache_free+0x195/0x610 mm/slub.c:6785
ppp_prepare_tx_skb drivers/net/ppp/ppp_generic.c:1850 [inline]
__ppp_xmit_process drivers/net/ppp/ppp_generic.c:1676 [inline]
ppp_xmit_process+0x1147/0x1d90 drivers/net/ppp/ppp_generic.c:1706
ppp_write+0x2c6/0x400 drivers/net/ppp/ppp_generic.c:540
do_loop_readv_writev fs/read_write.c:850 [inline]
vfs_writev+0x4bd/0x990 fs/read_write.c:1059
do_pwritev fs/read_write.c:1153 [inline]
__do_sys_pwritev fs/read_write.c:1199 [inline]
__se_sys_pwritev fs/read_write.c:1194 [inline]
__x64_sys_pwritev+0x19f/0x2a0 fs/read_write.c:1194
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The buggy address belongs to the object at ffff88811262cc00
which belongs to the cache skbuff_head_cache of size 240
The buggy address is located 228 bytes inside of
freed 240-byte region [ffff88811262cc00, ffff88811262ccf0)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x11262c
head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0x17ff00000000040(head|node=0|zone=2|lastcpupid=0x7ff)
page_type: f5(slab)
raw: 017ff00000000040 ffff8881616f28c0 ffffea00044a4780 dead000000000002
raw: 0000000000000000 0000000080150015 00000000f5000000 0000000000000000
head: 017ff00000000040 ffff8881616f28c0 ffffea00044a4780 dead000000000002
head: 0000000000000000 0000000080150015 00000000f5000000 0000000000000000
head: 017ff00000000001 ffffea0004498b01 00000000ffffffff 00000000ffffffff
head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000002
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 1, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 1, tgid 1 (swapper/0), ts 20587824573, free_ts 0
set_page_owner include/linux/page_owner.h:32 [inline]
post_alloc_hook+0x228/0x280 mm/page_alloc.c:1884
prep_new_page mm/page_alloc.c:1892 [inline]
get_page_from_freelist+0x24dc/0x2580 mm/page_alloc.c:3945
__alloc_frozen_pages_noprof+0x18d/0x380 mm/page_alloc.c:5240
alloc_pages_mpol+0x232/0x4a0 mm/mempolicy.c:2486
alloc_slab_page mm/slub.c:3075 [inline]
allocate_slab+0x86/0x3a0 mm/slub.c:3248
new_slab mm/slub.c:3302 [inline]
___slab_alloc+0xd82/0x1760 mm/slub.c:4656
__slab_alloc+0x65/0x100 mm/slub.c:4779
__slab_alloc_node mm/slub.c:4855 [inline]
slab_alloc_node mm/slub.c:5251 [inline]
kmem_cache_alloc_node_noprof+0x4b5/0x6f0 mm/slub.c:5315
__alloc_skb+0x1d0/0x7d0 net/core/skbuff.c:702
alloc_skb include/linux/skbuff.h:1383 [inline]
nlmsg_new include/net/netlink.h:1055 [inline]
rtmsg_ifinfo_build_skb+0x84/0x260 net/core/rtnetlink.c:4407
rtmsg_ifinfo_event net/core/rtnetlink.c:4449 [inline]
rtmsg_ifinfo+0x8c/0x1a0 net/core/rtnetlink.c:4458
register_netdevice+0x175f/0x1ae0 net/core/dev.c:11458
register_netdev+0x40/0x60 net/core/dev.c:11522
nr_proto_init+0x14a/0x720 net/netrom/af_netrom.c:1424
do_one_initcall+0x250/0x840 init/main.c:1378
do_initcall_level+0x104/0x190 init/main.c:1440
page_owner free stack trace missing
Memory state around the buggy address:
ffff88811262cb80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff88811262cc00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff88811262cc80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fc fc
^
ffff88811262cd00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff88811262cd80: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
***
If these findings have caused you to resend the series or submit a
separate fix, please add the following tag to your commit message:
Tested-by: syzbot@syzkaller.appspotmail.com
---
This report is generated by a bot. It may contain errors.
syzbot ci engineers can be reached at syzkaller@googlegroups.com.
On Mon, Feb 9, 2026 at 3:29 PM syzbot ci <syzbot+ci73cb85ac9652d7d4@syzkaller.appspotmail.com> wrote: > > syzbot ci has tested the following series > > [v1] ppp: don't store tx skb in the fastpath > https://lore.kernel.org/all/20260209021134.21194-1-dqfext@gmail.com > * [RFC PATCH net-next] ppp: don't store tx skb in the fastpath > > and found the following issue: > KASAN: slab-use-after-free Write in sk_skb_reason_drop > > Full report is available here: > https://ci.syzbot.org/series/0307aa1e-223a-4cd7-af71-1a3c3b7b33f0 > > *** > > KASAN: slab-use-after-free Write in sk_skb_reason_drop > > tree: net-next > URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/netdev/net-next.git > base: 57be33f85e369ce9f69f61eaa34734e0d3bd47a7 > arch: amd64 > compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8 > config: https://ci.syzbot.org/builds/3b8a7fc0-258a-4d96-b4cf-cf828112415c/config > C repro: https://ci.syzbot.org/findings/43f9458e-e8a7-4c35-83a9-fd92f2c65af4/c_repro > syz repro: https://ci.syzbot.org/findings/43f9458e-e8a7-4c35-83a9-fd92f2c65af4/syz_repro > > ================================================================== > BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:96 [inline] > BUG: KASAN: slab-use-after-free in atomic_fetch_sub_release include/linux/atomic/atomic-instrumented.h:400 [inline] > BUG: KASAN: slab-use-after-free in __refcount_sub_and_test include/linux/refcount.h:389 [inline] > BUG: KASAN: slab-use-after-free in __refcount_dec_and_test include/linux/refcount.h:432 [inline] > BUG: KASAN: slab-use-after-free in refcount_dec_and_test include/linux/refcount.h:450 [inline] > BUG: KASAN: slab-use-after-free in skb_unref include/linux/skbuff.h:1292 [inline] > BUG: KASAN: slab-use-after-free in __sk_skb_reason_drop net/core/skbuff.c:1226 [inline] > BUG: KASAN: slab-use-after-free in sk_skb_reason_drop+0x37/0x170 net/core/skbuff.c:1254 > Write of size 4 at addr ffff88811262cce4 by task syz.0.17/5962 > > CPU: 1 UID: 0 PID: 5962 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) > Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 > Call Trace: > <TASK> > dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120 > print_address_description mm/kasan/report.c:378 [inline] > print_report+0xba/0x230 mm/kasan/report.c:482 > kasan_report+0x117/0x150 mm/kasan/report.c:595 > check_region_inline mm/kasan/generic.c:-1 [inline] > kasan_check_range+0x264/0x2c0 mm/kasan/generic.c:200 > instrument_atomic_read_write include/linux/instrumented.h:96 [inline] > atomic_fetch_sub_release include/linux/atomic/atomic-instrumented.h:400 [inline] > __refcount_sub_and_test include/linux/refcount.h:389 [inline] > __refcount_dec_and_test include/linux/refcount.h:432 [inline] > refcount_dec_and_test include/linux/refcount.h:450 [inline] > skb_unref include/linux/skbuff.h:1292 [inline] > __sk_skb_reason_drop net/core/skbuff.c:1226 [inline] > sk_skb_reason_drop+0x37/0x170 net/core/skbuff.c:1254 > kfree_skb_reason include/linux/skbuff.h:1322 [inline] > kfree_skb include/linux/skbuff.h:1331 [inline] > ppp_push+0x1284/0x1440 drivers/net/ppp/ppp_generic.c:-1 > __ppp_xmit_process drivers/net/ppp/ppp_generic.c:1680 [inline] > ppp_xmit_process+0x9d7/0x1d90 drivers/net/ppp/ppp_generic.c:1706 > ppp_write+0x2c6/0x400 drivers/net/ppp/ppp_generic.c:540 > do_loop_readv_writev fs/read_write.c:850 [inline] > vfs_writev+0x4bd/0x990 fs/read_write.c:1059 > do_pwritev fs/read_write.c:1153 [inline] > __do_sys_pwritev fs/read_write.c:1199 [inline] > __se_sys_pwritev fs/read_write.c:1194 [inline] > __x64_sys_pwritev+0x19f/0x2a0 fs/read_write.c:1194 > do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] > do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94 > entry_SYSCALL_64_after_hwframe+0x77/0x7f > RIP: 0033:0x7f1a1d39acb9 > Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48 > RSP: 002b:00007ffc1381da18 EFLAGS: 00000246 ORIG_RAX: 0000000000000128 > RAX: ffffffffffffffda RBX: 00007f1a1d615fa0 RCX: 00007f1a1d39acb9 > RDX: 0000000000000001 RSI: 00002000000002c0 RDI: 0000000000000003 > RBP: 00007f1a1d408bf7 R08: 0000000000000001 R09: 0000000000000000 > R10: 0000000000000007 R11: 0000000000000246 R12: 0000000000000000 > R13: 00007f1a1d615fac R14: 00007f1a1d615fa0 R15: 00007f1a1d615fa0 > </TASK> > > Allocated by task 5962: > kasan_save_stack mm/kasan/common.c:57 [inline] > kasan_save_track+0x3e/0x80 mm/kasan/common.c:78 > unpoison_slab_object mm/kasan/common.c:340 [inline] > __kasan_slab_alloc+0x6c/0x80 mm/kasan/common.c:366 > kasan_slab_alloc include/linux/kasan.h:253 [inline] > slab_post_alloc_hook mm/slub.c:4953 [inline] > slab_alloc_node mm/slub.c:5263 [inline] > kmem_cache_alloc_node_noprof+0x427/0x6f0 mm/slub.c:5315 > __alloc_skb+0x1d0/0x7d0 net/core/skbuff.c:702 > alloc_skb include/linux/skbuff.h:1383 [inline] > ppp_write+0xb1/0x400 drivers/net/ppp/ppp_generic.c:523 > do_loop_readv_writev fs/read_write.c:850 [inline] > vfs_writev+0x4bd/0x990 fs/read_write.c:1059 > do_pwritev fs/read_write.c:1153 [inline] > __do_sys_pwritev fs/read_write.c:1199 [inline] > __se_sys_pwritev fs/read_write.c:1194 [inline] > __x64_sys_pwritev+0x19f/0x2a0 fs/read_write.c:1194 > do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] > do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94 > entry_SYSCALL_64_after_hwframe+0x77/0x7f > > Freed by task 5962: > kasan_save_stack mm/kasan/common.c:57 [inline] > kasan_save_track+0x3e/0x80 mm/kasan/common.c:78 > kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:584 > poison_slab_object mm/kasan/common.c:253 [inline] > __kasan_slab_free+0x5c/0x80 mm/kasan/common.c:285 > kasan_slab_free include/linux/kasan.h:235 [inline] > slab_free_hook mm/slub.c:2540 [inline] > slab_free mm/slub.c:6674 [inline] > kmem_cache_free+0x195/0x610 mm/slub.c:6785 > ppp_prepare_tx_skb drivers/net/ppp/ppp_generic.c:1850 [inline] > __ppp_xmit_process drivers/net/ppp/ppp_generic.c:1676 [inline] > ppp_xmit_process+0x1147/0x1d90 drivers/net/ppp/ppp_generic.c:1706 > ppp_write+0x2c6/0x400 drivers/net/ppp/ppp_generic.c:540 > do_loop_readv_writev fs/read_write.c:850 [inline] > vfs_writev+0x4bd/0x990 fs/read_write.c:1059 > do_pwritev fs/read_write.c:1153 [inline] > __do_sys_pwritev fs/read_write.c:1199 [inline] > __se_sys_pwritev fs/read_write.c:1194 [inline] > __x64_sys_pwritev+0x19f/0x2a0 fs/read_write.c:1194 > do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] > do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94 > entry_SYSCALL_64_after_hwframe+0x77/0x7f I missed that ppp_send_frame() can allocate a new skb and free the old one. Will fix it later. > > The buggy address belongs to the object at ffff88811262cc00 > which belongs to the cache skbuff_head_cache of size 240 > The buggy address is located 228 bytes inside of > freed 240-byte region [ffff88811262cc00, ffff88811262ccf0) > > The buggy address belongs to the physical page: > page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x11262c > head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 > flags: 0x17ff00000000040(head|node=0|zone=2|lastcpupid=0x7ff) > page_type: f5(slab) > raw: 017ff00000000040 ffff8881616f28c0 ffffea00044a4780 dead000000000002 > raw: 0000000000000000 0000000080150015 00000000f5000000 0000000000000000 > head: 017ff00000000040 ffff8881616f28c0 ffffea00044a4780 dead000000000002 > head: 0000000000000000 0000000080150015 00000000f5000000 0000000000000000 > head: 017ff00000000001 ffffea0004498b01 00000000ffffffff 00000000ffffffff > head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000002 > page dumped because: kasan: bad access detected > page_owner tracks the page as allocated > page last allocated via order 1, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 1, tgid 1 (swapper/0), ts 20587824573, free_ts 0 > set_page_owner include/linux/page_owner.h:32 [inline] > post_alloc_hook+0x228/0x280 mm/page_alloc.c:1884 > prep_new_page mm/page_alloc.c:1892 [inline] > get_page_from_freelist+0x24dc/0x2580 mm/page_alloc.c:3945 > __alloc_frozen_pages_noprof+0x18d/0x380 mm/page_alloc.c:5240 > alloc_pages_mpol+0x232/0x4a0 mm/mempolicy.c:2486 > alloc_slab_page mm/slub.c:3075 [inline] > allocate_slab+0x86/0x3a0 mm/slub.c:3248 > new_slab mm/slub.c:3302 [inline] > ___slab_alloc+0xd82/0x1760 mm/slub.c:4656 > __slab_alloc+0x65/0x100 mm/slub.c:4779 > __slab_alloc_node mm/slub.c:4855 [inline] > slab_alloc_node mm/slub.c:5251 [inline] > kmem_cache_alloc_node_noprof+0x4b5/0x6f0 mm/slub.c:5315 > __alloc_skb+0x1d0/0x7d0 net/core/skbuff.c:702 > alloc_skb include/linux/skbuff.h:1383 [inline] > nlmsg_new include/net/netlink.h:1055 [inline] > rtmsg_ifinfo_build_skb+0x84/0x260 net/core/rtnetlink.c:4407 > rtmsg_ifinfo_event net/core/rtnetlink.c:4449 [inline] > rtmsg_ifinfo+0x8c/0x1a0 net/core/rtnetlink.c:4458 > register_netdevice+0x175f/0x1ae0 net/core/dev.c:11458 > register_netdev+0x40/0x60 net/core/dev.c:11522 > nr_proto_init+0x14a/0x720 net/netrom/af_netrom.c:1424 > do_one_initcall+0x250/0x840 init/main.c:1378 > do_initcall_level+0x104/0x190 init/main.c:1440 > page_owner free stack trace missing > > Memory state around the buggy address: > ffff88811262cb80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc > ffff88811262cc00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb > >ffff88811262cc80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fc fc > ^ > ffff88811262cd00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc > ffff88811262cd80: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb > ================================================================== > > > *** > > If these findings have caused you to resend the series or submit a > separate fix, please add the following tag to your commit message: > Tested-by: syzbot@syzkaller.appspotmail.com > > --- > This report is generated by a bot. It may contain errors. > syzbot ci engineers can be reached at syzkaller@googlegroups.com.
© 2016 - 2026 Red Hat, Inc.