Commit 556ac52b authored by Pali Rohár's avatar Pali Rohár Committed by Steve French

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: default avatarPali Rohár <pali@kernel.org>
Reviewed-by: default avatarPaulo Alcantara (Red Hat) <pc@manguebit.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent e2a8910a
...@@ -330,6 +330,18 @@ static int parse_reparse_posix(struct reparse_posix_data *buf, ...@@ -330,6 +330,18 @@ static int parse_reparse_posix(struct reparse_posix_data *buf,
switch ((type = le64_to_cpu(buf->InodeType))) { switch ((type = le64_to_cpu(buf->InodeType))) {
case NFS_SPECFILE_LNK: 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, data->symlink_target = cifs_strndup_from_utf16(buf->DataBuffer,
len, true, len, true,
cifs_sb->local_nls); cifs_sb->local_nls);
...@@ -341,8 +353,19 @@ static int parse_reparse_posix(struct reparse_posix_data *buf, ...@@ -341,8 +353,19 @@ static int parse_reparse_posix(struct reparse_posix_data *buf,
break; break;
case NFS_SPECFILE_CHR: case NFS_SPECFILE_CHR:
case NFS_SPECFILE_BLK: 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_FIFO:
case NFS_SPECFILE_SOCK: 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; break;
default: default:
cifs_dbg(VFS, "%s: unhandled inode type: 0x%llx\n", cifs_dbg(VFS, "%s: unhandled inode type: 0x%llx\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment