CIFS: fix wrapping bugs in num_entries()
The problem is that "entryptr + next_offset" and "entryptr + len + size" can wrap. I ended up changing the type of "entryptr" because it makes the math easier when we don't have to do so much casting. Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Steve French <stfrench@microsoft.com> Reviewed-by: Aurelien Aptel <aaptel@suse.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> CC: Stable <stable@vger.kernel.org>
This commit is contained in:
parent
8ad8aa3535
commit
56446f218a
|
@ -3577,33 +3577,38 @@ num_entries(char *bufstart, char *end_of_buf, char **lastentry, size_t size)
|
|||
int len;
|
||||
unsigned int entrycount = 0;
|
||||
unsigned int next_offset = 0;
|
||||
FILE_DIRECTORY_INFO *entryptr;
|
||||
char *entryptr;
|
||||
FILE_DIRECTORY_INFO *dir_info;
|
||||
|
||||
if (bufstart == NULL)
|
||||
return 0;
|
||||
|
||||
entryptr = (FILE_DIRECTORY_INFO *)bufstart;
|
||||
entryptr = bufstart;
|
||||
|
||||
while (1) {
|
||||
entryptr = (FILE_DIRECTORY_INFO *)
|
||||
((char *)entryptr + next_offset);
|
||||
|
||||
if ((char *)entryptr + size > end_of_buf) {
|
||||
if (entryptr + next_offset < entryptr ||
|
||||
entryptr + next_offset > end_of_buf ||
|
||||
entryptr + next_offset + size > end_of_buf) {
|
||||
cifs_dbg(VFS, "malformed search entry would overflow\n");
|
||||
break;
|
||||
}
|
||||
|
||||
len = le32_to_cpu(entryptr->FileNameLength);
|
||||
if ((char *)entryptr + len + size > end_of_buf) {
|
||||
entryptr = entryptr + next_offset;
|
||||
dir_info = (FILE_DIRECTORY_INFO *)entryptr;
|
||||
|
||||
len = le32_to_cpu(dir_info->FileNameLength);
|
||||
if (entryptr + len < entryptr ||
|
||||
entryptr + len > end_of_buf ||
|
||||
entryptr + len + size > end_of_buf) {
|
||||
cifs_dbg(VFS, "directory entry name would overflow frame end of buf %p\n",
|
||||
end_of_buf);
|
||||
break;
|
||||
}
|
||||
|
||||
*lastentry = (char *)entryptr;
|
||||
*lastentry = entryptr;
|
||||
entrycount++;
|
||||
|
||||
next_offset = le32_to_cpu(entryptr->NextEntryOffset);
|
||||
next_offset = le32_to_cpu(dir_info->NextEntryOffset);
|
||||
if (!next_offset)
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue