From: Luxiao Xu gprs_xmit() forwards the incoming L3 skb directly to pep_write(). When a server-side pipe has negotiated PN_PIPE_SB_ALIGNED_DATA, pep_write() skips the wrapper skb allocation and calls pipe_skb_send() on the original skb. pipe_skb_send() prepends the pipe header with skb_push(), and pn_send() prepends the Phonet header with skb_push() as well. However, the GPRS netdev advertises hard_header_len = 0 and does not set needed_headroom. If an skb with insufficient headroom (such as one redirected from a veth interface) is transmitted on an aligned GPRS pipe, skb_push() underflows the skb headroom and triggers a kernel BUG via skb_under_panic(). Ensure sufficient headroom in pep_write() using skb_cow_head() before sending the skb on an aligned pipe. If reallocation fails, drop the skb and return -ENOMEM. Fixes: fea93ecef619 ("Phonet: zero-copy GPRS TX") Cc: stable@vger.kernel.org Reported-by: VEGA Closes: https://bugtracker.nebusec.ai/f/1935 Assisted-by: LLM Signed-off-by: Luxiao Xu Signed-off-by: Ren Wei --- net/phonet/pep.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/phonet/pep.c b/net/phonet/pep.c index bd1cdd00edfa..9d24b370fb7c 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -1259,8 +1259,13 @@ int pep_write(struct sock *sk, struct sk_buff *skb) struct sk_buff *rskb, *fs; int flen = 0; - if (pep_sk(sk)->aligned) + if (pep_sk(sk)->aligned) { + if (skb_cow_head(skb, MAX_PNPIPE_HEADER)) { + kfree_skb(skb); + return -ENOMEM; + } return pipe_skb_send(sk, skb); + } rskb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC); if (!rskb) { -- 2.43.0