mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
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 <pali@kernel.org> Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.com> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
e2a8910af0
commit
556ac52bb1
@ -330,6 +330,18 @@ static int parse_reparse_posix(struct reparse_posix_data *buf,
|
||||
|
||||
switch ((type = le64_to_cpu(buf->InodeType))) {
|
||||
case NFS_SPECFILE_LNK:
|
||||
if (len == 0 || (len % 2)) {
|
||||
cifs_dbg(VFS, "srv returned malformed nfs symlink buffer\n");
|
||||
return -EIO;
|
||||
}
|
||||
/*
|
||||
* Check that buffer does not contain UTF-16 null codepoint
|
||||
* because Linux cannot process symlink with null byte.
|
||||
*/
|
||||
if (UniStrnlen((wchar_t *)buf->DataBuffer, len/2) != len/2) {
|
||||
cifs_dbg(VFS, "srv returned null byte in nfs symlink target location\n");
|
||||
return -EIO;
|
||||
}
|
||||
data->symlink_target = cifs_strndup_from_utf16(buf->DataBuffer,
|
||||
len, true,
|
||||
cifs_sb->local_nls);
|
||||
@ -341,8 +353,19 @@ static int parse_reparse_posix(struct reparse_posix_data *buf,
|
||||
break;
|
||||
case NFS_SPECFILE_CHR:
|
||||
case NFS_SPECFILE_BLK:
|
||||
/* DataBuffer for block and char devices contains two 32-bit numbers */
|
||||
if (len != 8) {
|
||||
cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type);
|
||||
return -EIO;
|
||||
}
|
||||
break;
|
||||
case NFS_SPECFILE_FIFO:
|
||||
case NFS_SPECFILE_SOCK:
|
||||
/* DataBuffer for fifos and sockets is empty */
|
||||
if (len != 0) {
|
||||
cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type);
|
||||
return -EIO;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cifs_dbg(VFS, "%s: unhandled inode type: 0x%llx\n",
|
||||
|
Loading…
Reference in New Issue
Block a user