Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag '4.19-rc3-smb3-cifs' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs fixes from Steve French:
"Fixes for four CIFS/SMB3 potential pointer overflow issues, one minor
build fix, and a build warning cleanup"

* tag '4.19-rc3-smb3-cifs' of git://git.samba.org/sfrench/cifs-2.6:
cifs: read overflow in is_valid_oplock_break()
cifs: integer overflow in in SMB2_ioctl()
CIFS: fix wrapping bugs in num_entries()
cifs: prevent integer overflow in nxt_dir_entry()
fs/cifs: require sha512
fs/cifs: suppress a string overflow warning

+43 -17
+1
fs/cifs/Kconfig
··· 6 6 select CRYPTO_MD4 7 7 select CRYPTO_MD5 8 8 select CRYPTO_SHA256 9 + select CRYPTO_SHA512 9 10 select CRYPTO_CMAC 10 11 select CRYPTO_HMAC 11 12 select CRYPTO_ARC4
+8 -3
fs/cifs/cifssmb.c
··· 601 601 } 602 602 603 603 count = 0; 604 + /* 605 + * We know that all the name entries in the protocols array 606 + * are short (< 16 bytes anyway) and are NUL terminated. 607 + */ 604 608 for (i = 0; i < CIFS_NUM_PROT; i++) { 605 - strncpy(pSMB->DialectsArray+count, protocols[i].name, 16); 606 - count += strlen(protocols[i].name) + 1; 607 - /* null at end of source and target buffers anyway */ 609 + size_t len = strlen(protocols[i].name) + 1; 610 + 611 + memcpy(pSMB->DialectsArray+count, protocols[i].name, len); 612 + count += len; 608 613 } 609 614 inc_rfc1001_len(pSMB, count); 610 615 pSMB->ByteCount = cpu_to_le16(count);
+8
fs/cifs/misc.c
··· 402 402 (struct smb_com_transaction_change_notify_rsp *)buf; 403 403 struct file_notify_information *pnotify; 404 404 __u32 data_offset = 0; 405 + size_t len = srv->total_read - sizeof(pSMBr->hdr.smb_buf_length); 406 + 405 407 if (get_bcc(buf) > sizeof(struct file_notify_information)) { 406 408 data_offset = le32_to_cpu(pSMBr->DataOffset); 407 409 410 + if (data_offset > 411 + len - sizeof(struct file_notify_information)) { 412 + cifs_dbg(FYI, "invalid data_offset %u\n", 413 + data_offset); 414 + return true; 415 + } 408 416 pnotify = (struct file_notify_information *) 409 417 ((char *)&pSMBr->hdr.Protocol + data_offset); 410 418 cifs_dbg(FYI, "dnotify on %s Action: 0x%x\n",
+9 -2
fs/cifs/readdir.c
··· 376 376 377 377 new_entry = old_entry + sizeof(FIND_FILE_STANDARD_INFO) + 378 378 pfData->FileNameLength; 379 - } else 380 - new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset); 379 + } else { 380 + u32 next_offset = le32_to_cpu(pDirInfo->NextEntryOffset); 381 + 382 + if (old_entry + next_offset < old_entry) { 383 + cifs_dbg(VFS, "invalid offset %u\n", next_offset); 384 + return NULL; 385 + } 386 + new_entry = old_entry + next_offset; 387 + } 381 388 cifs_dbg(FYI, "new entry %p old entry %p\n", new_entry, old_entry); 382 389 /* validate that new_entry is not past end of SMB */ 383 390 if (new_entry >= end_of_smb) {
+17 -12
fs/cifs/smb2pdu.c
··· 2459 2459 /* We check for obvious errors in the output buffer length and offset */ 2460 2460 if (*plen == 0) 2461 2461 goto ioctl_exit; /* server returned no data */ 2462 - else if (*plen > 0xFF00) { 2462 + else if (*plen > rsp_iov.iov_len || *plen > 0xFF00) { 2463 2463 cifs_dbg(VFS, "srv returned invalid ioctl length: %d\n", *plen); 2464 2464 *plen = 0; 2465 2465 rc = -EIO; 2466 2466 goto ioctl_exit; 2467 2467 } 2468 2468 2469 - if (rsp_iov.iov_len < le32_to_cpu(rsp->OutputOffset) + *plen) { 2469 + if (rsp_iov.iov_len - *plen < le32_to_cpu(rsp->OutputOffset)) { 2470 2470 cifs_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n", *plen, 2471 2471 le32_to_cpu(rsp->OutputOffset)); 2472 2472 *plen = 0; ··· 3577 3577 int len; 3578 3578 unsigned int entrycount = 0; 3579 3579 unsigned int next_offset = 0; 3580 - FILE_DIRECTORY_INFO *entryptr; 3580 + char *entryptr; 3581 + FILE_DIRECTORY_INFO *dir_info; 3581 3582 3582 3583 if (bufstart == NULL) 3583 3584 return 0; 3584 3585 3585 - entryptr = (FILE_DIRECTORY_INFO *)bufstart; 3586 + entryptr = bufstart; 3586 3587 3587 3588 while (1) { 3588 - entryptr = (FILE_DIRECTORY_INFO *) 3589 - ((char *)entryptr + next_offset); 3590 - 3591 - if ((char *)entryptr + size > end_of_buf) { 3589 + if (entryptr + next_offset < entryptr || 3590 + entryptr + next_offset > end_of_buf || 3591 + entryptr + next_offset + size > end_of_buf) { 3592 3592 cifs_dbg(VFS, "malformed search entry would overflow\n"); 3593 3593 break; 3594 3594 } 3595 3595 3596 - len = le32_to_cpu(entryptr->FileNameLength); 3597 - if ((char *)entryptr + len + size > end_of_buf) { 3596 + entryptr = entryptr + next_offset; 3597 + dir_info = (FILE_DIRECTORY_INFO *)entryptr; 3598 + 3599 + len = le32_to_cpu(dir_info->FileNameLength); 3600 + if (entryptr + len < entryptr || 3601 + entryptr + len > end_of_buf || 3602 + entryptr + len + size > end_of_buf) { 3598 3603 cifs_dbg(VFS, "directory entry name would overflow frame end of buf %p\n", 3599 3604 end_of_buf); 3600 3605 break; 3601 3606 } 3602 3607 3603 - *lastentry = (char *)entryptr; 3608 + *lastentry = entryptr; 3604 3609 entrycount++; 3605 3610 3606 - next_offset = le32_to_cpu(entryptr->NextEntryOffset); 3611 + next_offset = le32_to_cpu(dir_info->NextEntryOffset); 3607 3612 if (!next_offset) 3608 3613 break; 3609 3614 }