unsigned int len;
        u64 type;
 
+       len = le16_to_cpu(buf->ReparseDataLength);
+       if (len < sizeof(buf->InodeType)) {
+               cifs_dbg(VFS, "srv returned malformed nfs buffer\n");
+               return -EIO;
+       }
+
+       len -= sizeof(buf->InodeType);
+
        switch ((type = le64_to_cpu(buf->InodeType))) {
        case NFS_SPECFILE_LNK:
-               len = le16_to_cpu(buf->ReparseDataLength);
                data->symlink_target = cifs_strndup_from_utf16(buf->DataBuffer,
                                                               len, true,
                                                               cifs_sb->local_nls);
        u32 tag = data->reparse.tag;
 
        if (tag == IO_REPARSE_TAG_NFS && buf) {
+               if (le16_to_cpu(buf->ReparseDataLength) < sizeof(buf->InodeType))
+                       return false;
                switch (le64_to_cpu(buf->InodeType)) {
                case NFS_SPECFILE_CHR:
+                       if (le16_to_cpu(buf->ReparseDataLength) != sizeof(buf->InodeType) + 8)
+                               return false;
                        fattr->cf_mode |= S_IFCHR;
                        fattr->cf_rdev = reparse_mkdev(buf->DataBuffer);
                        break;
                case NFS_SPECFILE_BLK:
+                       if (le16_to_cpu(buf->ReparseDataLength) != sizeof(buf->InodeType) + 8)
+                               return false;
                        fattr->cf_mode |= S_IFBLK;
                        fattr->cf_rdev = reparse_mkdev(buf->DataBuffer);
                        break;