CVE-2026-98954 in Linuxالمعلومات

الملخص

بحسب VulDB • 23/10/2026

في نواة لينكس، تم حل الثغرة التالية:

net: دائمًا تفكيك حزم GSO في __virtio_net_hdr_to_skb()

أضاف الالتزام 9e8db5913264 ("net: تجنب الإيجابيات الكاذبة في التحقق من صحة gso غير الموثوق به") فحصًا '&& skb->network_header' قبل تقسيم تدفق حزم GSO التي لا تحتوي على VIRTIO_NET_HDR_F_NEEDS_CSUM داخل __virtio_net_hdr_to_skb()، لأن بعض المتصلين (مثل tun_get_user(), وtun_xdp_one(), وvirtnet_receive_done(), وraw_verify_header()) كانوا يستدعون virtio_net_hdr_*_to_skb() قبل تهيئة skb->network_header وskb->dev.

نظرًا لأن __alloc_skb() و__build_skb_around() يقومان بتصفير (zero-initialize) skb->network_header إلى 0 (على عكس mac_header وtransport_header اللذين يتم تهيئتهما إلى ~0U)، كان لدى هؤلاء المتصلين الأربعة دائمًا قيمة skb->network_header تساوي 0، مما سمح لهم بالتجاوز لتقسيم التدفق في __virtio_net_hdr_to_skb(). بشكل أعم، يمثل skb->network_header إزاحة (offset) منskb->head (حيث أن القيمة 0 هي أيضًا إزاحة صالحة كلما كانت skb_headroom(skb) تساوي 0)، وليست علمًا boolean.

عندما كان يتم تخطي فرع 'if (gso_type && skb->network_header)'، كان التراجع إلى 'else if (gso_type)' يسحب فقط nh_min_len + thlen (40 بايت لـ TCPv4) دون تفكيك الحزمة، ودون التحقق من ip_proto أو n_proto، ودون تعيين skb->transport_header.

إذا كانت الحزمة تحتوي على رأس شبكة معيب (malformed network header)، فإنها لا تُرفض، ويؤدي فحص skb_probe_transport_header() اللاحق إلى الفشل أيضًا، مما يترك skb->transport_header عند ~0U (0xffff). وبالمثل، إذا حملت حزمة IPv4 خيارات IP (ihl > 5) أو حملت حزمة IPv6 رؤوس امتداد، فإن سحب nh_min_len + thlen فقط قد يترك رأس TCP خارج نطاقskb->head. في كلتا الحالتين، يقوم tcp_hdrlen(skb) الموجود في skb_gso_transport_seglen() بقراءة بيانات من خارج النطاق (out-of-bounds):

BUG: KASAN: slab-out-of-bounds in skb_gso_transport_seglen Read of size 2 by task poc/133 skb_gso_transport_seglen (net/core/gso.c:155) skb_gso_validate_mac_len (net/core/gso.c:270) tbf_enqueue (net/sched/sch_tbf.c:260) dev_qdisc_enqueue (net/core/dev.c:4227) __dev_queue_xmit (net/core/dev.c:4884)

بالإضافة إلى ذلك، كان التحقق من virtio_net_hdr_match_proto() داخل 'if (!skb->protocol)' فقط قبل تقسيم التدفق يتسبب في تخطي التحقق عندما يكون skb->protocol قد تم تعيينه مسبقًا بواسطة المتصل، ويرفض إطارات VLAN-tagged التي يكون فيها بروتوكول L2 الخارجي هو ETH_P_8021Q أو ETH_P_8021AD.

تم إصلاح هذا عن طريق: 1. تهيئة skb->dev وskb->network_header (بالإضافة إلى skb->protocol لـ IFF_TUN) قبل استدعاء virtio_net_hdr_*_to_skb() في tun_get_user(), وtun_xdp_one(), وvirtnet_receive_done(), وraw_verify_header(). وفي tun_get_user(), تم إزالة إعادة تعيين mac_header الزائدة عن الحاجة (skb_reset_mac_header(skb)) في حالة IFF_TUN لأن __virtio_net_hdr_to_skb() يعيد ضبط mac_header بشكل غير مشروط. 2. إزالة '&& skb->network_header' والتراجع غير المدقق 'else if (gso_type)' في __virtio_net_hdr_to_skb() بحيث يتم تقسيم تدفق جميع حزم GSO التي لا تحتوي على VIRTIO_NET_HDR_F_NEEDS_CSUM، ويتم سحب رأس النقل إلى البيانات الخطية (linear data)، وتعيين skb->transport_header. 3. نقل فحص virtio_net_hdr_match_proto() ليتم بعد استدعاء skb_flow_dissect_flow_keys_basic(), والتحقق من keys.basic.n_proto مقابل hdr_gso_type.

Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.

مسؤول

Linux

حجز

25/09/2026

إفشاء

23/10/2026

الاعتدال

تمت الموافقة

إدخال

VDB-425710

EPSS

0.00000

KEV

لا

النشاطات

منخفض

المصادر

Do you need the next level of professionalism?

Upgrade your account now!