Linux kernel是美国Linux基金会发布的操作系统Linux所使用的内核。NFSv4 implementation是其中的一个分布式文件系统协议。 Linux Kernel的fs/cifs/connect.c文件中的CIFSTCon()函数存在缓冲区溢出漏洞。如果用户受骗连接到了恶意的服务器且服务器向客户端返回了特制的Tree Connect响应的话,就可以出发这个溢出,导致执行任意代码。以下是有漏洞的代码段: 3441 int 3442 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, 3443 const char *tree, struct cifsTconInfo *tcon, 3444 const struct nls_table *nls_codepage) 3445 { 3446 struct smb_hdr *smb_buffer; 3447 struct smb_hdr *smb_buffer_response; 3448 TCONX_REQ *pSMB; 3449 TCONX_RSP *pSMBr; 3450 unsigned char *bcc_ptr; 3451 int rc = 0; 3452 int length; 3453 __u16 count; ... 3458 smb_buffer = cifs_buf_get(); ... 3561 if (smb_buffer->;Flags2 & SMBFLG2_UNICODE) { 3562 length = UniStrnlen((wchar_t *) bcc_ptr, 512); 3563 if ((bcc_ptr + (2 * length)) - 3564 pByteArea(smb_buffer_response) <= 3565 BCC(smb_buffer_response)) { 3566 kfree(tcon->;nativeFileSystem); 3567 tcon->;nativeFileSystem = 3568 kzalloc(length + 2, GFP_KERNEL); ... 3579 /* else do not bother copying these information...
Linux kernel是美国Linux基金会发布的操作系统Linux所使用的内核。NFSv4 implementation是其中的一个分布式文件系统协议。 Linux Kernel的fs/cifs/connect.c文件中的CIFSTCon()函数存在缓冲区溢出漏洞。如果用户受骗连接到了恶意的服务器且服务器向客户端返回了特制的Tree Connect响应的话,就可以出发这个溢出,导致执行任意代码。以下是有漏洞的代码段: 3441 int 3442 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, 3443 const char *tree, struct cifsTconInfo *tcon, 3444 const struct nls_table *nls_codepage) 3445 { 3446 struct smb_hdr *smb_buffer; 3447 struct smb_hdr *smb_buffer_response; 3448 TCONX_REQ *pSMB; 3449 TCONX_RSP *pSMBr; 3450 unsigned char *bcc_ptr; 3451 int rc = 0; 3452 int length; 3453 __u16 count; ... 3458 smb_buffer = cifs_buf_get(); ... 3561 if (smb_buffer->;Flags2 & SMBFLG2_UNICODE) { 3562 length = UniStrnlen((wchar_t *) bcc_ptr, 512); 3563 if ((bcc_ptr + (2 * length)) - 3564 pByteArea(smb_buffer_response) <= 3565 BCC(smb_buffer_response)) { 3566 kfree(tcon->;nativeFileSystem); 3567 tcon->;nativeFileSystem = 3568 kzalloc(length + 2, GFP_KERNEL); ... 3579 /* else do not bother copying these information fields*/ ... 3606 cifs_buf_release(smb_buffer); 3607 return rc; 3608 } 如果用户所控制的smb_buffer缓冲区(3458行)为Unicode(3561行),就会使用UniStrnlen()计算其长度。如果长度小于或等于smb_buffer_response的字节数,会使用fs/cifs/cifspdu.h中定义的BCC()宏: 416 /* given a pointer to an smb_hdr retrieve the value of byte count */ 417 #define BCC(smb_var) (*(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->;WordCount))) 418 #define BCC_LE(smb_var) (*(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->;WordCount))) 之后释放所分配的原始文件系统内存(3566行),并在3568行使用kzalloc()重新分配。这个大小应足够储存unicode字符串,但没有执行(length + 1) * 2,而是执行了length + 2,因此分配了不充分的缓冲区。