LinuxÄÚºËTCPºÍ̸¶à¸öSACKÖ°Äܻؾø·þÎñ·ì϶·ÖÎö

°ä²¼¹¦·ò 2019-06-21
·ì϶²¼¾°


2019Äê6ÔÂ18ÈÕ£¬Redhat°ä²¼°²È«²¼¸æ£¬LinuxÄÚºËTCP/IPºÍ̸ջ´æÔÚ3¸ö°²È«·ì϶£¨CVE-2019-11477/CVE-2019-11478/CVE-2019-11479£©£¬ÕâЩ·ì϶Óë×î´ó·Ö¶Î´óÐ ¡£¨MSS£©ºÍTCPÑ¡ÔñÐÔÈ·ÈÏ£¨SACK£©Ö°ÄÜÓйØ£¬ÔÊÐíÔ¶³Ì¹¥»÷Õß½øÐлؾø·þÎñ¹¥»÷ ¡£


¹Ø¼ü¸ÅÏë



Êý¾Ý°ü³Á´«È·ÈÏ»úÔì


TCPÊý¾Ý°ü´«Êä¹ý³ÌÖУ¬À´×Ô»¬¶¯´°¿ÚµÄÊý¾Ý°üÃÔʧ¿ÉÄܶÔTCPÍÌÍÂÁ¿²úÉúÓ°Ïì ¡£TCPʹÓÃÀÛ»ýÈ·ÈÏ£¨ACK£©¹æ»®½â¾ö¸ÃÎÊÌ⣬ÆäÖв»½Ó¹Ü²»ÔÚ»¬¶¯´°¿Ú×ó±ßÔµµÄ½Ó¹Ü¶Î£¬Õâ»áÇ¿Ôì·¢ËÍ·½ÆÚ´ýÍù·µ¹¦·òÒÔÕÒ³öÿ¸öÃÔʧµÄÊý¾Ý°ü£¬»òÕß²»Óø¹µØ³Áд«ÊäÒÑÕýÈ·½Ó¹ÜµÄ¶Î£¬´Ó¶ø½µµÍÕûÌåÍÌÍÂÁ¿ ¡£


Ñ¡ÔñÐÔÈ·ÈÏ£¨SACK£©ÊÇÒ»ÖÖÔÚ¶à¸öÅׯúµÄ¶ÎµÄÇé¿öϽâ¾ö´ËÐÐΪµÄÕ½Êõ ¡£Í¨¹ýÑ¡ÔñÐÔÈ·ÈÏ£¬Êý¾Ý½Ó¹Ü·½Äܹ»Ïò·¢ËÍ·½Í¨ÖªÒѳɹ¦´ïµ½µÄËùÓжΣ¬Òò¶ø·¢ËÍ·½Ö»Ðè³Áд«ÊäÏÖʵÃÔʧµÄ¶Î ¡£¾ßÌåÑ¡ÔñÐÔÈ·ÈϹý³Ì£¬ÈçÏÂͼËùʾ ¡£


GA»Æ½ð¼×¡¤(ÖйúÇø)¹Ù·½ÍøÕ¾


×î´ó·Ö¶Î´óÐ ¡£¨Maximum Segment Size£©


MSS£¨Maximum Segment Size£¬×î´ó±¨ÎĶδóÐ ¡£©µÄ¸ÅÏëÊÇÖ¸TCP²ãËù¿ÉÄܽӹܵÄ×î´ó·Ö¶Î´óÓ×£¬¸ÃÖµÖ»Ô̺¬TCP¶ÎµÄÊý¾Ý²¿ÃÅ£¬²»Ô̺¬Option²¿ÃÅ ¡£Áí±í£¬ÔÚTCPÊײ¿ÓÐÒ»¸öMSSÑ¡ÏÔÚÈý´ÎÎÕÊÖ¹ý³ÌÖУ¬TCP·¢ËͶËʹÓøÃÑ¡Ïî֪ͨ¶Ô·½×Ô¼ºËùÄܽÓÊܵÄ×î´ó·Ö¶Î´óÓ× ¡£


TSO£¨TCP Segmentation Offload£©


TSOÊÇÒ»ÖÖÀûÓÃÍø¿¨À´¶Ô´óÊý¾Ý°ü½øÐÐ×Ô¶¯·Ö¶Î£¬½µµÍCPU¸ºÔصļ¼Êõ ¡£ÆäÖØÒªÊÇÑÓ³¤·Ö¶Î ¡£


GSO(Generic Segmentation Offload)


GSOÊǺÍ̸ջÊÇ·ñÍÆ³Ù·Ö¶Î£¬ÔÚ·¢Ë͵½Íø¿¨Ö®Ç°ÅжÏÍø¿¨ÊÇ·ñÖ§³ÖTSO£¬ÈôÊÇÍø¿¨Ö§³ÖTSOÔòÈÃÍø¿¨·Ö¶Î£¬²»È»ºÍ̸ջ·ÖÍê¶ÎÔÙ½»¸øÇý¶¯ ¡£ÈôÊÇTSO¿ªÆô£¬GSO»á×Ô¶¯¿ªÆô ¡£


·ì϶µÀÀí


CVE-2019-11477


ƾ¾Ý²¹¶¡¿ÉÖª£¬¸Ã·ì϶ÊÇÓÉÒ»¸ö16bitÎÞ·ûºÅÊýÒç³öµ¼ÖµÄ£¬¸ÃÎÞ·ûºÅÊý´æÔÚÈçϽṹÌåÖÐ ¡£


GA»Æ½ð¼×¡¤(ÖйúÇø)¹Ù·½ÍøÕ¾


¸Ãtcp_skb_cb½á¹¹Ìå´æ·Å×ÅTCPÿ¸öÊý¾Ý°üµÄ½ÚÔìÐÅÏ¢£¬Æ¾¾Ý×¢½â¿ÉÖª£¬tcp_gso_segs/sizeÖ»ÓÃÓÚд¶ÓÁйý³ÌÖÐ ¡£


LinuxÄÚºËTCP/IPºÍ̸ջʵÏÖÖУ¬Ã¿¸öÊý¾Ý»º³åÇøÊÇÓÉÒ»¸ösk_buff½á¹¹ÌåͳһÖÎÀíµÄ ¡£ÔÚÒ»¸öÆëÈ«µÄÊý¾Ý»º³åÇøÖÐskb_endºóÃæ½ôËæ×ÅÒ»¸öskb_shared_info½á¹¹ÌåÊý¾Ý£¬skb_shared_info½á¹¹ÌåÈçÏÂËùʾ£º


GA»Æ½ð¼×¡¤(ÖйúÇø)¹Ù·½ÍøÕ¾


½á¹¹Ìå×îºóÒ»¸ö³ÉÔ±ÊÇfrags[MAX_SKB_FRAGS]Êý¾Ý ¡£MAX_SKB_FRAGSÉêÃ÷ÈçÏÂËùʾ£º

GA»Æ½ð¼×¡¤(ÖйúÇø)¹Ù·½ÍøÕ¾


PAGE_SIZEΪ4KBÇé¿öÏ£¨¼´Ò»¸öÄÚ´æÒ³ÃæÎª4KB´óÐ ¡£©£¬MAX_SKB_FRAGSȡֵΪ65536/4096 + 1¼´17£¬Òò¶øÒ»¸öskbÖÐ×î¶à°üÈÝ17¸öÊý¾Ý·Ôì¬ ¡£¶ÔÓÚx86ϵͳ£¬Ã¿¸öÊý¾Ý·Ôì¬×î¶àÄܹ»¼Í¼32KBÊý¾ÝµÄ´óÓ× ¡£
Êý¾Ý·Ôì¬skb_frag_struct½á¹¹ÌåÈçÏÂËùʾ£º


GA»Æ½ð¼×¡¤(ÖйúÇø)¹Ù·½ÍøÕ¾


ÔÚÕû¸öºÍ̸ջ²Ù×÷¹ý³ÌÖУ¬Êý¾Ý°ü¼ÈÒª½øÐÐIP±»·Ô쬵Ä£¬ÓÖÒª½øÐÐTCP·Ö¶Î ¡£´«ÊäÊý¾Ýʱ£¬ºÍ̸ջ»áƾ¾ÝGSOÖµ£¬MSSÖµÒÔ¼°»¬¶¯´°¿ÚÈýÕßÖ®¼äµÄ´óÓ×¹ØÏµÅжÏÊÇ·ñ½øÐзÔì¬ ¡£²¢Í¨¹ýtcp_set_skb_tso_segs()º¯ÊýÉèÖÃGSO£¬¾ßÌåʵÏÖÈçÏÂͼËùʾ£º


GA»Æ½ð¼×¡¤(ÖйúÇø)¹Ù·½ÍøÕ¾


ÈôÊÇskb->len´óÓÚmss_now£¬ÐÐ1207£¬½«tcp_gso_segsÉèÖÃΪskb->len/mss_now ¡£ÐÐ1208£¬½«tcp_gso_sizeÉèÖÃΪmss_now ¡£


ÈôÊÇÆôÓÃÁËSACK£¬ÔÚ²úÉú¶ª°üºó£¬½Ó¹Ü¶Ë»á·µ»ØSACK¿é£¬SACK¿éÖмͼ³ÁÃÔʧ°üµÄÐòÁбàºÅ ¡£·¢ËͶ˻á½âÎöSACK¿éÖмͼµÄÃÔʧ°üÐòÁбàºÅ£¬²¢³Áд«Ê䣬²¢ÇÒÔÚÒ»¸ö»¬¶¯´°¿ÚÖпÉÄÜÔ̺¬¶à¸öSACK¿é£¬SACK¿éÖÐÒ²¿ÉÄÜÔ̺¬¶à¸öskb¶ÓÁÐ ¡£ÔÚTCP³Á´«Êý¾Ý°ü¹ý³ÌÖУ¬Äܹ»½«¶à¸öskb¶ÓÁй鲢µ½Ò»¸öskb¶ÓÁÐÖнøÐгÁ´« ¡£


tcp_shift_skb_data()º¯ÊýʵÏÖÕâ¸öÖ°ÄÜ ¡£³¢ÊÔ½«ÓâÔ½¶à¸öskbµÄSACK¿éÕÛµþΪһ¸öskb ¡£¹Ø¼ü´úÂëÈçÏ£º


GA»Æ½ð¼×¡¤(ÖйúÇø)¹Ù·½ÍøÕ¾


skb_shift()ºÍtcp_shifted_skb()Á½¸öº¯ÊýÖØÒªÊµÏÖ¸ÃÖ°ÄÜ ¡£³Á´«¹ý³ÌÖжà¸öskb¶ÓÁй鲢µ½Ò»¸öskb¶ÓÁÐÖУ¬ÈôÊÇÌî³ä17¸ö·Ô쬵½×î´óÈÝÁ¿£¬ 17*32*1024/8=69632£¬ÒѾ­´óÓÚ65535£¬µ¼ÖÂÎÞ·ûºÅÕûÊýÒç³ö ¡£


ÔÚskb_shift ()º¯ÊýÖУ¬tcp_gso_segsÒç³öºó£¬½øÈëtcp_shifted_skb()º¯Êýºó£¬ÈçÏÂËùʾ£º


GA»Æ½ð¼×¡¤(ÖйúÇø)¹Ù·½ÍøÕ¾


ÐÐ1299£¬ÅжÏtcp_gso_segsºÍpcountµÄ´óÓ×£¬ÈôÊÇtcp_gas_segsÓ×ÓÚpcount£¬BUG_ON¶ÏÑÔ´¥·¢µ¼ÖÂÄں˱ÀÀ£ ¡£


ƾ¾Ý²¹¶¡¿ÉÖª£¬skb_shift()±»tcp_skb_shift()°ü°ì£¬Ö»ÊǼÓÁËÁ½¸öÅжÏ£¬ÈçÏÂËùʾ£º

GA»Æ½ð¼×¡¤(ÖйúÇø)¹Ù·½ÍøÕ¾


²¹¶¡Æ½±ðÀëÅжÏÁËskb->len+shift_len²»ÄÜ´óÓÚ65535*8×Ö½ÚºÍtcp_skb_pcount(to) + pcount²»ÄÜ´óÓÚ65535 ¡£µÚÒ»¸öÅжÏ£¬skb->lenÊǰµÊ¾sk_buff½á¹¹ÌåÖаµÊ¾payload³¤¶È£¬shift_len°µÊ¾Òª¹é²¢µ½skbÖеÄpayload ¡£


CVE-2019-11478


¸Ã·ì϶ҲÊÇÕûÊýÒç³ö£¬ÔÚÊý¾Ý°ü³Áд«Êä¹ý³ÌÖУ¬½«´«Êä¶ÓÁзֶÎΪ¶à¸ö΢Ó×µÄskbs£¬ÅòÕÍskbÖÐд¶ÓÁÐÄÚ´æ²úÉúÒç³ö ¡£ÔÚ´¦ÖÃSACK¿éÖÐÔ̺¬µÄskb²¢½«Æä¹é²¢ºó£¬Æ¾¾ÝGSOÅжϽøÐÐÊÇ·ñ·Ô쬣¬ÈôÊDZØÒª£¬Å²ÓÃtcp_fragement()º¯Êý½øÐзÔì¬ ¡£Æ¾¾Ý²¹¶¡¿ÉÖª£º


GA»Æ½ð¼×¡¤(ÖйúÇø)¹Ù·½ÍøÕ¾


²¹¶¡ÔÚtcp_fragment()º¯ÊýÖвÎÓëÁË×îÓ׿ռäÅжÏ ¡£SkÊÇsock½á¹¹ÌåÀàÐÍ£¬Ã¿Ò»¸ötcpÁ´½Ó¶ÔÓ¦Ò»¸ö ¡£ËùÒÔËùÓÐÒª·¢Ë͵ÄskbÊý¾Ý´óÓ×¶¼ÒªÀÛ¼Óµ½sk->sk_wmem_queuedÖУ¬sk->sk_wmem_queued°µÊ¾Îª¸ÃÌ×½Ó×ÖTCPд¶ÓÁлº³åÇø´óÓ× ¡£Í¨³£ÔÚʹÓÃʱ³½±ØÒªÅжϸÃÖµÊÇ·ñ¹»Óà ¡£ÈçÏÂËùʾ£º


GA»Æ½ð¼×¡¤(ÖйúÇø)¹Ù·½ÍøÕ¾


ƾ¾Ý×¢½â¿ÉÖª£¬ÅжÏ×îÐÂÁжÓskb°üËùÐèµÄ×îÓ׿Éд¿Õ¼ä ¡£²¹¶¡ÖУ¬ÅжÏÔü×Ò·¢ËÍ»º´æÎª´óÓÚµÅ×Úµ±Ç°·¢ËͶÓÁÐÕ¼ÓÿռäµÄÒ»°ë£¬¼´»¹ÓÐ1/3ÒÔÉϵĿÕÓà¿Õ¼äʱ£¬²¢ÇÒÓ×ÓÚsk->sk_sndbuf·¢·îÉÏÏÞÄÜÁ¦¹»Õý³£·¢ËÍ£¬²»È»¾ÍÅж¨TCPд¶ÓÁÐÌ«´ó ¡£


CVE-2019-11479


¸Ã·ì϶ÓÉÓÚ¹ý¶È¿÷Ëð×ÊÔ´µ¼Ö»ؾø·þÎñ ¡£ÈôÊǶñÒâÊý¾Ý°ü½«MSSÑ¡ÏîÉèÖóɽÏÓ×Öµ£¬Õ⽫ÆÈʹºÍÌ¸Õ»ÆÆ·Ñ¼«¶È¸ßµÄÍøÂç»òCPU×ÊÔ´·¢ËÍÊý¾Ý°ü¿ªÏú ¡£LinuxÄÚºËÖн«MSS_NOWÓ²±àÂëΪ48 ¡£Æ¾¾Ý²¹¶¡¿ÉÖª£º

GA»Æ½ð¼×¡¤(ÖйúÇø)¹Ù·½ÍøÕ¾


½øÐÐÁËmax×î´óÖµÅжÏ£¬¶ø²»ÔÙÊǹ̶¨Ó²±àÂë ¡£ÕâÀïµÄsysctl_tcp_min_snd_mss±»ÉèÖÃΪ65535£¬ÈçÏÂËùʾ£º


GA»Æ½ð¼×¡¤(ÖйúÇø)¹Ù·½ÍøÕ¾


Ô¤·ÀÁ˹¥»÷ÕßʹÓü«Ó×MSSÖµ ¡£


Ó°Ïì°æ±¾¼°²¹¶¡½¨¸´


ʵʱ¸üÐÂ×îв¹¶¡»ò½ûÓÃSACKºÍ¹ýÂ˼«Ó×MSSµÄÊý¾Ý°ü ¡£


CVE-2019-11477

Ó°Ïì°æ±¾£º

  • Linux 2.6.29 ~ 4.19.13£¨stable kernel releases 4.4.182,  4.9.182, 4.14.127, 4.19.52, 5.1.11Ö®±í£©

  • RHEL 8 (kernel, kernel-rt)£¬RHEL 7 (kernel, kernel-rt)£¬RHEL 6

½ûÓÃsack£º

  • sudo sysctl -w net.ipv4.tcp_sack=0

²¹¶ ¡£º

  • https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/?id=3b4929f65b0d8249f19a50245cd88ed1a2f78cff

CVE-2019-11478

Ó°Ïì°æ±¾£º

  • Linux 2.6.29 ~ 4.19.13£¨stable kernel releases 4.4.182,  4.9.182, 4.14.127, 4.19.52, 5.1.11Ö®±í£©

  • RHEL 8 (kernel, kernel-rt)£¬RHEL 7 (kernel, kernel-rt)£¬RHEL 6£¬RHEL 5

½ûÓÃsack£º

  • sudo sysctl -w net.ipv4.tcp_sack=0

²¹¶ ¡£º

  • https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/?id=f070ef2ac66716357066b683fb0baf55f8191a2e

CVE-2019-11479

Ó°Ïì°æ±¾£º

  • Linux 2.6.29 ~ 4.19.13£¨stable kernel releases 4.4.182,  4.9.182, 4.14.127, 4.19.52, 5.1.11Ö®±í£©

  • RHEL 8 (kernel, kernel-rt)£¬RHEL 7 (kernel, kernel-rt)£¬RHEL 6£¬RHEL 5

¹ýÂ˺ÅÁ

  • sudo iptables -A INPUT -p tcp -m tcpmss --mss 1:500 -j DROP

¹Ø¹Øtcp_mtu_probing£º

  • sysctl net.ipv4.tcp_mtu_probing

²¹¶ ¡£º

  • https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/?id=5f3e2bf008c2221478101ee72f5cb4654b9fc363

  • https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/?id=967c05aee439e6e5d7d805e195b3a20ef5c433d6