[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <lsq.1544392233.154984642@decadent.org.uk>
Date: Sun, 09 Dec 2018 21:50:33 +0000
From: Ben Hutchings <ben@...adent.org.uk>
To: linux-kernel@...r.kernel.org, stable@...r.kernel.org
CC: akpm@...ux-foundation.org, "Steve French" <stfrench@...rosoft.com>,
"Pavel Shilovsky" <pshilov@...rosoft.com>,
"Aurelien Aptel" <aaptel@...e.com>,
"Dan Carpenter" <dan.carpenter@...cle.com>
Subject: [PATCH 3.16 237/328] CIFS: fix wrapping bugs in num_entries()
3.16.62-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <dan.carpenter@...cle.com>
commit 56446f218af1133c802dad8e9e116f07f381846c upstream.
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@...cle.com>
Signed-off-by: Steve French <stfrench@...rosoft.com>
Reviewed-by: Aurelien Aptel <aaptel@...e.com>
Reviewed-by: Pavel Shilovsky <pshilov@...rosoft.com>
Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
---
fs/cifs/smb2pdu.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -2148,33 +2148,38 @@ num_entries(char *bufstart, char *end_of
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;
}
Powered by blists - more mailing lists