CVE-2023-53667CVE-2023-53667是Linux内核中cdc_ncm(CDC Network Control Model)USB网络驱动的一个安全漏洞。该漏洞源于驱动在处理USB设备描述符中的dwNtbOutMaxSize字段时,未能充分验证其最小值。在cdc_ncm_check_tx_max()函数中,当dwNtbOutMaxSize值低于计算出的最小值但大于零时,逻辑会将其设置为tx_max值,随后在cdc_ncm_fill_tx_frame()中用于分配SKB(Socket Buffer)。由于alloc_skb()在分配内存时会进行对齐操作(SKB_DATA_ALIGN),分配的内存大小可能不足以容纳SKB头部和CDC数据。当前实现中,512字节的分配空间减去320字节的SKB头部后仅剩192字节用于172字节的CDC数据,勉强可用。但如果SKB头部结构(如struct skb_shared_info)增加字段导致头部变大,CDC数据将无法放入剩余空间,从而触发skb_over_panic内核BUG,导致系统崩溃。该漏洞需要本地低权限访问,但可在特定条件下通过恶意USB设备或受控的USB网络适配器触发内核拒绝服务。
该漏洞的技术原理如下:在cdc_ncm_check_tx_max()函数中,驱动从USB设备读取dwNtbOutMaxSize参数,该参数定义了NTB(Network Transfer Block)的最大输出大小。当该值过低但非零时,驱动将其作为SKB分配大小传递给alloc_skb()。alloc_skb()内部会执行size = SKB_DATA_ALIGN(size) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))的对齐操作。当前情况下,分配512字节,SKB头部占用320字节,剩余192字节空间恰好容纳172字节的CDC数据。但这是一个脆弱的平衡——若skb_shared_info结构体增加字段(如3个u64共24字节),头部变为344字节(对齐后384字节),剩余空间仅128字节,无法容纳172字节的CDC数据。在cdc_ncm_ndp16()中调用skb_put_zero()写入数据时,会触发skb_over_panic,调用链为:skb_put() -> skb_put_zero() -> cdc_ncm_ndp16() -> cdc_ncm_fill_tx_frame() -> cdc_ncm_tx_fixup()。修复方案是将dwNtbOutMaxSize限制在[USB_CDC_NCM_NTB_MIN_OUT_SIZE, CDC_NCM_NTB_MAX_SIZE_TX]范围内,确保分配足够的空间容纳CDC数据。