From cb2ce357899dedf46e0972efbb55803dfd857c64 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 13 Aug 2026 15:15:40 -0400 Subject: [PATCH] MT#55283 handle non-linear skbuffs Convert skb to linear by making a copy if it isn't already, so that all data can be easily accessed. Change-Id: Iea4005ac0e650fea3c20eebe0da251d839dda7b5 --- kernel-module/nft_rtpengine.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/kernel-module/nft_rtpengine.c b/kernel-module/nft_rtpengine.c index d6bbf87b7..601491e93 100644 --- a/kernel-module/nft_rtpengine.c +++ b/kernel-module/nft_rtpengine.c @@ -6636,6 +6636,9 @@ static struct sk_buff *rtpe_skb_cpy(const struct sk_buff *oskb, const struct rtp atomic64_inc(&t->skb_copies); + if (!rtp) + return skb; + // adjust RTP pointers *rtp2 = *rtp; offset = skb->data - oskb->data; @@ -7152,8 +7155,6 @@ static int rtpengine46(struct sk_buff *oskb, datalen -= sizeof(*uh); DBG("udp payload = %u\n", datalen); - data = ((unsigned char *) uh) + sizeof(*uh); - // all our outputs filled? _r_lock(&g->outputs_lock, flags); if (g->outputs_unfilled) { @@ -7163,6 +7164,17 @@ static int rtpengine46(struct sk_buff *oskb, } _r_unlock(&g->outputs_lock, flags); + // prepare to access payload of packet. make sure it's a flat buffer + // XXX could be smarter about this, we usually just need the header + if (skb_needs_linearize(oskb, 0)) { + skb = rtpe_skb_cpy(oskb, NULL, NULL, t); + if (!skb) + goto out_error; + uh = udp_hdr(skb); + } + + data = ((unsigned char *) uh) + sizeof(*uh); + if (is_stun(g, datalen, data)) goto out_target; @@ -7238,7 +7250,7 @@ static int rtpengine46(struct sk_buff *oskb, g->target.ssrc_stats); // copy to decrypt/authenticate needed? - if (g->target.decrypt.hmac != REH_NULL || g->decrypt_rtp.cipher->decrypt_rtp) { + if (!skb && (g->target.decrypt.hmac != REH_NULL || g->decrypt_rtp.cipher->decrypt_rtp)) { errstr = "out of memory"; skb = rtpe_skb_cpy(oskb, &rtp, &rtp, t); if (!skb) @@ -7303,10 +7315,12 @@ static int rtpengine46(struct sk_buff *oskb, // always make a copy for RTCP // (even if technically not needed for NF_DROP case below) - errstr = "out of memory"; - skb = rtpe_skb_cpy(oskb, &rtp, &rtp, t); - if (!skb) - goto out_error; + if (!skb) { + errstr = "out of memory"; + skb = rtpe_skb_cpy(oskb, &rtp, &rtp, t); + if (!skb) + goto out_error; + } rtpe_pull_trim(skb, datalen); @@ -7330,8 +7344,10 @@ static int rtpengine46(struct sk_buff *oskb, } else { // forward non-RTP/RTCP. no copy needed - skb = skb_get(oskb); - atomic64_inc(&t->skb_refs); + if (!skb) { + skb = skb_get(oskb); + atomic64_inc(&t->skb_refs); + } nf_action = NF_DROP; rtpe_pull_trim(skb, datalen);