LinuxÄÚºËAF_PACKETÔ­ÉúÌ×½Ó×Ö©¶´£¨CVE-2020-14386£©·ÖÎö

Ðû²¼Ê±¼ä 2020-09-22

©¶´Åä¾°


½üÈÕ£¬OpenwallÉçÇøÉϹûÈ»ÁËÒ»¸öLinuxÄÚºËAF_PACKETÔ­ÉúÌ×½Ó×ÖÄÚ´æÆÆ»µÂ©¶´ ¡£Æ¾¾Ýϸ½ÚÃèÊö£¬¸Ã©¶´·ºÆðÔÚnet/packet/af_packet.cÖУ¬ÓÉÕûÊýÒç³öµ¼ÖÂÔ½½çд£¬¿ÉÒÔͨ¹ýËü½øÐÐȨÏÞÌáÉý ¡£¸Ã©¶´Î£º¦ÆÀ¼¶Îª¸ß£¬±àºÅΪCVE-2020-14386 ¡£


ÊÜÓ°Ïì²úÎïºÍ»º½â´ëÊ©


1¡¢ÊÜÓ°Ïì²úÎï


¸Ã©¶´Ó°ÏìLinux¿¯Ðаæ¸ßÓÚ4.6µÄÄں˰汾£¬°üÂÞ£º

  • Ubuntu Bionic (18.04) and newer

  • Debian 9

  • Debian 10

  • CentOS 8/RHEL 8

2¡¢»º½â´ëÊ©


£¨1£©ÐÞ²¹ÏµÍ³

ÉÏÓÎÄں˲¹¶¡ÈçÏ£º

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=acf69c946233259ab4d64f8869d4037a198c7f06


£¨2£©¹Ø±ÕCAP_NET_RAW¹¦Ð§

Õë¶ÔRHEL8£¬¾ßÌå¹Ø±Õ²½ÖèÈçÏ£º

# echo"user.max_user_namespaces=0" > /etc/sysctl.d/userns.conf

# sysctl -p/etc/sysctl.d/userns.conf


£¨3£©Õë¶ÔһЩÊÜÓ°ÏìµÄÈÝÆ÷²úÎͬÑù½ÓÄɹرÕCAP_NET_RAW¹¦Ð§½øÐлº½â

Kubernetes PodÄþ¾²¼Æı£ºÅäÖÃPodÄþ¾²¼ÆıÒÔɾ³ýÔËÐÐÈÝÆ÷ÖеÄCAP_NET_RAW¹¦Ð§£¬²Î¿¼Á´½Ó£ºhttps://cloud.google.com/kubernetes-engine/docs/security-bulletins ¡£


Ïà¹Ø¿´·¨


1¡¢AF_PACKETÌ×½Ó×Ö


ÍøÂçЭÒéÕ»ÖУ¬Ô­Ê¼Ì×½Ó×ÖÊÇÒ»¸öÌØÊâµÄÌ×½Ó×ÖÀàÐÍ£¬´ÓʵÏÖÉÏ¿ÉÒÔ·ÖΪÁ½À࣬һÀàΪÁ´Â·²ãԭʼÌ×½Ó×Ö£»ÁíÒ»ÀàΪÍøÂç²ãԭʼÌ×½Ó×Ö ¡£Á´Â·²ãԭʼÌ×½Ó×Ö¿ÉÖ±½ÓÓÃÓÚ½ÓÊպͷ¢ËÍÁ´Â·²ãµÄMACÖ¡£¬ÔÚ·¢ËÍʱÐèÒªµ÷ÓÃÕß×ÔÐнṹºÍ·â×°MACÊײ¿ ¡£Á´Â·²ãԭʼÌ×½Ó×Öµ÷ÓÃsocket()º¯Êý´´½¨ ¡£µÚÒ»¸ö²ÎÊýÖ¸¶¨µØÖ·´ØÀàÐÍΪAF_PACKET£¬µÚ¶þ¸ö²ÎÊýÌ×½Ó×ÖÀàÐÍΪSOCK_RAW»òSOCK_DGRAM£¬µ±ÀàÐÍÖ¸¶¨ÎªSOCK_RAWʱ£¬Ì×½Ó×Ö½ÓÊպͷ¢Ë͵ÄÊý¾Ý¶¼ÊÇ´ÓMACÊײ¿¿ªÊ¼µÄ ¡£ÔÚ·¢ËÍʱÐèÒªÓɵ÷ÓÃÕß´ÓMACÊײ¿¿ªÊ¼½á¹¹ºÍ·â×°±¨ÎÄÊý¾Ý ¡£


2¡¢PACKET_MMAP


½öÒÀ¿¿AF_PACKET¹ýÂËÊý¾Ý°üÊǷdz£µÍЧµÄ£¬ÄÚºËÓÖÌṩÁËPACKET_MMAPÖ§³Ö ¡£PACKET_MMAPÔÚÄں˿ռäÖзÖÅäÒ»¿é»·ÐÎÄں˻º³åÇø£¬Óû§¿Õ¼äͨ¹ýmmap½«¸ÃÄں˻º³åÇøÓ³Éä³öÀ´ ¡£ÊÕµ½µÄÊý¾Ý°ü¿½±´µ½»·ÐÎÄں˻º³åÇøÖУ¬Óû§²ã¿ÉÒÔÖ±½Ó²Ù×÷Êý¾Ý£¬Í¨¹ýÄں˿ռäºÍÓû§¿Õ¼ä¹²ÏíµÄ»º³åÇøÆðµ½¼õÉÙÊý¾Ý¿½±´µÄ×÷Óã¬Ìá¸ß´¦ÖÃЧÂÊ ¡£


PACKET_MMAPʵÏÖ¹ý³Ì


ͨ¹ýsetsockopt()º¯ÊýÉèÖû·Ðλº³åÇø£¬option²ÎÊýÉèÖÃΪPACKET_RX_RING»òPACKET_TX_RING ¡£ÎªÁË·½±ãÄÚºËÓëÓû§²ã¹ÜÀíºÍ½»»¥»·Ðλº³åÇøÖеÄÊý¾ÝÖ¡£¬Äں˽ç˵ÁËTPACKET_HEADER½á¹¹Ì壬¸Ã½á¹¹Ìå´æ´¢×ÅһЩԪÐÅÏ¢ÈçÌ×½Ó×ÖµØÖ·ÐÅÏ¢¡¢Ê±¼ä´ÁÒÔ¼°»·Ðλº³åÇø¹ÜÀíÐÅÏ¢µÈ ¡£Èç¹ûͨ¹ýsetsockopt()º¯ÊýÉèÖÃÁËPACKET_VNET_HDRÑ¡Ï»¹ÐèÌí¼ÓÒ»¸övirtio_net_hdr½á¹¹Ìå ¡£Ò»¸öÊý¾ÝÖ¡°üÂÞÁ½¸ö²¿ÃÅ£¬µÚÒ»²¿ÃÅΪTPACKET_HEADER£¬µÚ¶þ²¿ÃÅΪData£¬¶øÇÒÒª±£Ö¤Ò³Ãæ¶ÔÆ룬ÈçÏÂͼËùʾ£º

Ä¿Ç°TPACKET_HEADER´æÔÚÈý¸ö°æ±¾£¬Ã¿¸ö°æ±¾³¤¶ÈÂÔÓвîÒì ¡£¶ÔÓÚv1ºÍv2£¬ÊÕ·¢»·Ðλº³åÇøÓÃtpacket_req½á¹¹Ìå¹ÜÀí£¬¸Ã½á¹¹Ìå°üÂÞËĸöÊý¾ÝÓò£º·Ö±ðΪÄÚ´æ¿éµÄ¾ÞϸºÍÊýÁ¿¡¢Ã¿¸öÊý¾ÝÖ¡µÄ¾ÞϸºÍÊý¾ÝÖ¡×ÜÊý ¡£ÈçÏÂͼËùʾ£º



²¶×½µÄframe±»»®·ÖΪ¶à¸öblock£¬Ã¿¸öblockÊÇÒ»¿éÎïÀíÉÏÁ¬ÐøµÄÄÚ´æÇøÓò£¬ÓÐtp_block_size/tp_frame_size¸öframe£¬blockµÄ×ÜÊýÊÇtp_block_nr ¡£ÀýÈ磬tp_block_size = 4096£¬tp_frame_size = 2048£¬tp_block_nr = 4£¬tp_frame_nr = 8 ¡£µÃµ½µÄ»º³åÇø½á¹¹ÈçÏÂͼËùʾ£º



ÿ¸öframe±ØÐë·ÅÔÚÒ»¸öblockÖУ¬Ã¿¸öblockÉú´æÕûÊý¸öframe£¬Ò²¾ÍÊÇ˵һ¸öframe²»ÄÜ¿çÔ½Á½¸öblock ¡£ÔÚÓû§²ãÓ³Éä»·Ðλº³åÇø¿ÉÒÔÖ±½ÓʹÓÃmmap()º¯Êý ¡£ËäÈ»»·Ðλº³åÇøÔÚÄÚºËÖÐÊÇÓɶà¸öblock×é³ÉµÄ£¬µ«ÊÇÓ³ÉäºóËüÃÇÔÚÓû§¿Õ¼äÖÐÊÇÁ¬ÐøµÄ ¡£


©¶´·ÖÎö


¸Ã©¶´¾ßÌå·ºÆðÔÚtpacket_rcv()º¯ÊýÖУ¬¸Ãº¯ÊýÊÇ»ùÓÚPACKET_MMAPµÄÊý¾Ý°ü½ÓÊÕº¯Êý ¡£¾ßÌ幦ЧʵÏÖÈçÏ´úÂëËùʾ£º



ÐÐ2226µ½ÐÐ2228£¬Èç¹ûsk_typeΪSOCK_DGRAM£¬ÌåÏÖ²»ÐèÒª×ÔÐнṹMACÊײ¿£¬ÓÉÄÚºËÌî³ä£¬Ôòmacoff¼´ÊÇnetoff£¬¾ÞϸΪTPACKET_ALIGN(tp_hdr_len)+ 16 + tp_reserve ¡£Èç¹ûsk_typeΪSOCK_RAW£¬Ôò½øÈëÐÐ2230£¬ÌåÏÖÐèÒª×ÔÐнṹMACÊײ¿ ¡£ÐÐ2231µ½ÐÐ2233£¬Ê×ÏȼÆËãnetoff£¬¾ÞϸΪTPACKET_ALIGN(tp_hdrlen +(maclen < 16 ?16 : maclen)) + tp_reserve ¡£ÐÐ2234µ½ÐÐ2237£¬Èç¹ûÉèÖÃÁËPACKET_VNET_HDRÑ¡Ï»¹Ðè¼ÓÉÏÒ»¸övirtio_net_hdr½á¹¹ÌåµÄ¾Þϸ£¬È»ºóÉèÖÃdo_vnetΪÕæ ¡£ÐÐ2238£¬¼ÆËãmacoff ¡£


ÓÉÓÚmacoff¡¢netoffÒÔ¼°maclen±»½ç˵Ϊunsigned shortÀàÐÍ£¬×î´óֵΪ0xffff ¡£¶øtp_reserve±»½ç˵Ϊunsigned intÀàÐÍ£¬×î´óֵΪ0xffffffff£¬¶øÇÒ¾Þϸ¿ÉÒÔͨ¹ýsetsockopt()º¯Êý½øÐÐÉèÖã¬ÈçÏ´úÂëËùʾ£º



Òò´Ë£¬ÔÚ¼ÆËãnetoffʱ£¬¿ÉÒÔͨ¹ý¿ØÖÆtp_reserveÔì³ÉÕûÊýÒç³ö£¬½ø¶ø¼ÆËã¶éÂäÎóµÄmacoff ¡£µ±Ö´Ðе½ÈçÏ´úÂëʱ£º



ÐÐ2287£¬µ÷ÓÃvirtio_net_hdr_from_skb()º¯Êý´Ósk_buffÖп½±´Êý¾Ý£¬¸Ãº¯ÊýµÚ¶þ¸ö²ÎÊýΪh.raw + macoff ¨C sizeof(struct virtio_net_hdr)£¬h.rawΪtpacket_rcv_uhdrÀàÐ͵ÄÖ¸Õ룬ָÏò»·Ðλº³åÇøµÄframe£¬ÓÉÓÚmacoffÊǿɿصÄ£¬¿ÉÒÔÈÃmaoffСÓÚsizeof(struct virtio_net_hdr)£¬µ¼ÖÂÏòÇ°Ô½½çд£¬×î¶à¿ÉдÈësizeof(struct virtio_net_hdr)¸ö×Ö½Ú ¡£Æ¾¾ÝÌṩµÄPoC£¬µ÷ÊÔ´úÂëÈçÏÂͼËùʾ£º



rdxÖдæ·Å×ÅTPACKET_ALIGN(tp_hdrlen+(maclen < 16 ? 16 : maclen))£¬¾ÞϸΪ0x50 ¡£rbp+0x4e4´¦´æ·Å×Åpo->tp_reserve£¬¾ÞϸΪ0x0000ffb4 ¡£Ïà¼Óºó£¬ÕûÊýÉÏÒçºó£¬rdxΪ0x0004 ¡£µ±Ö´Ðе½Ô½½ç·ÃÎÊʱ£¬¾ßÌåÈçÏ£º



R9´æ·Å×Åh.rawÖ¸Õ룬rdx´æ·Å×Åmacoff£¬virtio_net_hdr½á¹¹Ìå¾ÞϸΪ0xa ¡£ÈçÏÂͼËùʾ£º



·¢ÉúÄÚ´æ·ÃÎÊ´íÎó£¬Ôì³ÉϵͳÍ߽⠡£


²Î¿¼Á´½Ó£º


[1] https://blog.csdn.net/sinat_20184565/article/details/82788387

[2] https://www.openwall.com/lists/oss-security/2020/09/03/3

[3] https://elixir.bootlin.com/linux/v5.6/source/Documentation/networking/packet_mmap.txt

[4] https://sysdig.com/blog/cve-2020-14386-falco/

[5] https://bugzilla.redhat.com/show_bug.cgi?id=1875699#c9