Messages in this thread Patch in this message | | | From | Shiming Cheng <> | Subject | [PATCH net] udp: fix segmentation crash for untrusted source packet | Date | Wed, 13 Mar 2024 21:34:02 +0800 |
| |
Kernel exception is reported when making udp frag list segmentation. Backtrace is as below: at out/android15-6.6/kernel-6.6/kernel-6.6/net/ipv4/udp_offload.c:229 at out/android15-6.6/kernel-6.6/kernel-6.6/net/ipv4/udp_offload.c:262 features=features@entry=19, is_ipv6=false) at out/android15-6.6/kernel-6.6/kernel-6.6/net/ipv4/udp_offload.c:289 features=19) at out/android15-6.6/kernel-6.6/kernel-6.6/net/ipv4/udp_offload.c:399 features=19) at out/android15-6.6/kernel-6.6/kernel-6.6/net/ipv4/af_inet.c:1418 skb@entry=0x0, features=19, features@entry=0) at out/android15-6.6/kernel-6.6/kernel-6.6/net/core/gso.c:53 tx_path=<optimized out>) at out/android15-6.6/kernel-6.6/kernel-6.6/net/core/gso.c:124
This packet's frag list is null while gso_type is not 0. Then it is treated as a GRO-ed packet and sent to segment frag list. Function call path is udp_rcv_segment => config features value __udpv4_gso_segment => skb_gso_ok returns false. Here it should be true. Failed reason is features doesn't match gso_type. __udp_gso_segment_list skb_segment_list => packet is linear with skb->next = NULL __udpv4_gso_segment_list_csum => use skb->next directly and crash happens
In rx-gro-list GRO-ed packet is set gso type as NETIF_F_GSO_UDP_L4 | NETIF_F_GSO_FRAGLIST in napi_gro_complete. In gso flow the features should also set them to match with gso_type. Or else it will always return false in skb_gso_ok. Then it can't discover the untrusted source packet and result crash in following function.
Fixes: f2696099c6c6 ("udp: Avoid post-GRO UDP checksum recalculation") Signed-off-by: Shiming Cheng <shiming.cheng@mediatek.com> Signed-off-by: Lena Wang <lena.wang@mediatek.com> --- include/net/udp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/net/udp.h b/include/net/udp.h index 488a6d2babcc..c87baa23b9da 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -464,7 +464,7 @@ void udpv6_encap_enable(void); static inline struct sk_buff *udp_rcv_segment(struct sock *sk, struct sk_buff *skb, bool ipv4) { - netdev_features_t features = NETIF_F_SG; + netdev_features_t features = NETIF_F_SG | NETIF_F_GSO_UDP_L4 | NETIF_F_GSO_FRAGLIST; struct sk_buff *segs; /* Avoid csum recalculation by skb_segment unless userspace explicitly -- 2.18.0
| |