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号