Linux内核TCP协议多个SACK功效拒绝服务误差剖析
宣布时间 2019-06-212019年6月18日,Redhat宣布清静通告,Linux内核TCP/IP协议栈保存3个清静误差(CVE-2019-11477/CVE-2019-11478/CVE-2019-11479),这些误差与最大分段大�。∕SS)和TCP选择性确认(SACK)功效相关,允许远程攻击者举行拒绝服务攻击。
要害看法
数据包重传确认机制
TCP数据包传输历程中,来自滑动窗口的数据包丧失可能对TCP吞吐量爆发影响。TCP使用累积确认(ACK)计划解决该问题,其中不吸收不在滑动窗口左边沿的吸收段,这会强制发送方期待往返时间以找出每个丧失的数据包,或者不须要地重新传输已准确吸收的段,从而降低整体吞吐量。
最大分段大�。∕aximum Segment Size)
MSS(Maximum Segment Size,最大报文段大�。┑目捶ㄊ侵窽CP层所能够吸收的最大分段巨细,该值只包括TCP段的数据部分,不包括Option部分。另外,在TCP首部有一个MSS选项,在三次握手历程中,TCP发送端使用该选项告诉对方自己所能接受的最大分段巨细。
TSO(TCP Segmentation Offload)
TSO是一种使用网卡来对大数据包举行自动分段,降低CPU负载的手艺。其主要是延迟分段。
GSO(Generic Segmentation Offload)
误差原理
CVE-2019-11477
该tcp_skb_cb结构体存放着TCP每个数据包的控制信息,凭证注释可知,tcp_gso_segs/size只用于写行列历程中。
结构体最后一个成员是frags[MAX_SKB_FRAGS]数据。MAX_SKB_FRAGS声明如下所示:
数据分片skb_frag_struct结构体如下所示:
在整个协议栈操作历程中,数据包既要举行IP被分片的,又要举行TCP分段。传输数据时,协议栈会凭证GSO值,MSS值以及滑动窗口三者之间的巨细关系判断是否举行分片。并通过tcp_set_skb_tso_segs()函数设置GSO,详细实现如下图所示:
若是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行列中举行重传。
skb_shift()和tcp_shifted_skb()两个函数主要实现该功效。重传历程中多个skb行列合并到一个skb行列中,若是填充17个分片到最大容量, 17*32*1024/8=69632,已经大于65535,导致无符号整数溢出。
行1299,判断tcp_gso_segs和pcount的巨细,若是tcp_gas_segs小于pcount,BUG_ON断言触发导致内核瓦解。
补丁中划分判断了skb->len+shift_len不可大于65535*8字节和tcp_skb_pcount(to) + pcount不可大于65535。第一个判断,skb->len是体现sk_buff结构体中体现payload长度,shift_len体现要合并到skb中的payload。
CVE-2019-11478
补丁在tcp_fragment()函数中加入了最小空间判断。Sk是sock结构体类型,每一个tcp链接对应一个。以是所有要发送的skb数据巨细都要累加到sk->sk_wmem_queued中,sk->sk_wmem_queued体现为该套接字TCP写行列缓冲区巨细。通常在使用时间需要判断该值是否够用。如下所示:
凭证注释可知,判断最新排队skb包所需的最小可写空间。补丁中,判断剩余发送缓存为大于即是目今发送行列占用空间的一半,即尚有1/3以上的空余空间时,并且小于sk->sk_sndbuf发送上限才可以正常发送,不然就判断TCP写行列太大。
CVE-2019-11479
阻止了攻击者使用极小MSS值。
影响版本及补丁修复
实时更新最新补丁或禁用SACK和过滤极小MSS的数据包。
|
CVE-2019-11477 |
影响版本:
|
|
禁用sack:
|
|
|
补�。�
|
|
|
CVE-2019-11478 |
影响版本:
|
|
禁用sack:
|
|
|
补�。�
|
|
|
CVE-2019-11479 |
影响版本:
|
|
过滤下令:
关闭tcp_mtu_probing:
|
|
|
补�。�
|


京公网安备11010802024551号