Skip to content

Commit 556ac52

Browse files
palismfrench
authored andcommitted
cifs: Validate content of NFS reparse point buffer
Symlink target location stored in DataBuffer is encoded in UTF-16. So check that symlink DataBuffer length is non-zero and even number. And check that DataBuffer does not contain UTF-16 null codepoint because Linux cannot process symlink with null byte. DataBuffer for char and block devices is 8 bytes long as it contains two 32-bit numbers (major and minor). Add check for this. DataBuffer buffer for sockets and fifos zero-length. Add checks for this. Signed-off-by: Pali Rohár <[email protected]> Reviewed-by: Paulo Alcantara (Red Hat) <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent e2a8910 commit 556ac52

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

fs/smb/client/reparse.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,18 @@ static int parse_reparse_posix(struct reparse_posix_data *buf,
330330

331331
switch ((type = le64_to_cpu(buf->InodeType))) {
332332
case NFS_SPECFILE_LNK:
333+
if (len == 0 || (len % 2)) {
334+
cifs_dbg(VFS, "srv returned malformed nfs symlink buffer\n");
335+
return -EIO;
336+
}
337+
/*
338+
* Check that buffer does not contain UTF-16 null codepoint
339+
* because Linux cannot process symlink with null byte.
340+
*/
341+
if (UniStrnlen((wchar_t *)buf->DataBuffer, len/2) != len/2) {
342+
cifs_dbg(VFS, "srv returned null byte in nfs symlink target location\n");
343+
return -EIO;
344+
}
333345
data->symlink_target = cifs_strndup_from_utf16(buf->DataBuffer,
334346
len, true,
335347
cifs_sb->local_nls);
@@ -341,8 +353,19 @@ static int parse_reparse_posix(struct reparse_posix_data *buf,
341353
break;
342354
case NFS_SPECFILE_CHR:
343355
case NFS_SPECFILE_BLK:
356+
/* DataBuffer for block and char devices contains two 32-bit numbers */
357+
if (len != 8) {
358+
cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type);
359+
return -EIO;
360+
}
361+
break;
344362
case NFS_SPECFILE_FIFO:
345363
case NFS_SPECFILE_SOCK:
364+
/* DataBuffer for fifos and sockets is empty */
365+
if (len != 0) {
366+
cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type);
367+
return -EIO;
368+
}
346369
break;
347370
default:
348371
cifs_dbg(VFS, "%s: unhandled inode type: 0x%llx\n",

0 commit comments

Comments
 (0)