summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQingfang Deng <qingfang.deng@linux.dev>2026-09-08 15:21:31 +0800
committerJakub Kicinski <kuba@kernel.org>2026-09-09 18:41:57 -0700
commit8aaeb56aff2a557a88f83ae866da2c91ad247e59 (patch)
tree9b47cc4ca7782909de720259a209dd529625f48d
parentbe83178bfc44588f6e3adb827ed874c683193466 (diff)
downloadlinux-next-8aaeb56aff2a557a88f83ae866da2c91ad247e59.tar.gz
linux-next-8aaeb56aff2a557a88f83ae866da2c91ad247e59.zip
ppp_synctty: ensure a writeable skb header
ppp_sync_txmunge() checks headroom before prepending the address and control bytes, but does not ensure that the skb header is writable. A received skb can reach this function through PPP channel bridging without passing through ppp_start_xmit(), which calls skb_cow_head(). For example, a PPPoE frame may share its buffer with a clone queued to an AF_PACKET socket. If it is bridged to a synchronous tty channel, the address/control bytes can overwrite data still visible to that socket. Use skb_cow_head() to ensure both sufficient headroom and a writable header. Fixes: 4cf476ced45d ("ppp: add PPPIOCBRIDGECHAN and PPPIOCUNBRIDGECHAN ioctls") Signed-off-by: Qingfang Deng <qingfang.deng@linux.dev> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260908072135.877364-1-qingfang.deng@linux.dev Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--drivers/net/ppp/ppp_synctty.c14
1 files changed, 3 insertions, 11 deletions
diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c
index f87d43faeeab..ebd62a7ab54b 100644
--- a/drivers/net/ppp/ppp_synctty.c
+++ b/drivers/net/ppp/ppp_synctty.c
@@ -455,17 +455,9 @@ ppp_sync_txmunge(struct syncppp *ap, struct sk_buff *skb)
/* prepend address/control fields if necessary */
if ((ap->flags & SC_COMP_AC) == 0 || islcp) {
- if (skb_headroom(skb) < 2) {
- struct sk_buff *npkt = dev_alloc_skb(skb->len + 2);
- if (npkt == NULL) {
- kfree_skb(skb);
- return NULL;
- }
- skb_reserve(npkt,2);
- skb_copy_from_linear_data(skb,
- skb_put(npkt, skb->len), skb->len);
- consume_skb(skb);
- skb = npkt;
+ if (skb_cow_head(skb, 2)) {
+ kfree_skb(skb);
+ return NULL;
}
skb_push(skb,2);
skb->data[0] = PPP_ALLSTATIONS;