Skip to content

Commit

Permalink
CIFS: fix wrapping bugs in num_entries()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dan Carpenter authored and Steve French committed Sep 12, 2018
1 parent 8ad8aa3 commit 56446f2
Showing 1 changed file with 15 additions and 10 deletions.
25 changes: 15 additions & 10 deletions fs/cifs/smb2pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down

0 comments on commit 56446f2

Please sign in to comment.