From: Luxiao Xu <redacted>
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: <redacted>
Reported-by: VEGA <redacted>
Closes: https://bugtracker.nebusec.ai/f/1935
Assisted-by: LLM
Signed-off-by: Luxiao Xu <redacted>
Signed-off-by: Ren Wei <redacted>
---
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