diff options
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r-- | fs/cifs/cifssmb.c | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index a3d74fea1623..ccd31ab815d4 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -463,7 +463,6 @@ decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr) | |||
463 | cifs_max_pending); | 463 | cifs_max_pending); |
464 | set_credits(server, server->maxReq); | 464 | set_credits(server, server->maxReq); |
465 | server->maxBuf = le16_to_cpu(rsp->MaxBufSize); | 465 | server->maxBuf = le16_to_cpu(rsp->MaxBufSize); |
466 | server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs); | ||
467 | /* even though we do not use raw we might as well set this | 466 | /* even though we do not use raw we might as well set this |
468 | accurately, in case we ever find a need for it */ | 467 | accurately, in case we ever find a need for it */ |
469 | if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { | 468 | if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { |
@@ -3089,7 +3088,8 @@ CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon, | |||
3089 | bool is_unicode; | 3088 | bool is_unicode; |
3090 | unsigned int sub_len; | 3089 | unsigned int sub_len; |
3091 | char *sub_start; | 3090 | char *sub_start; |
3092 | struct reparse_data *reparse_buf; | 3091 | struct reparse_symlink_data *reparse_buf; |
3092 | struct reparse_posix_data *posix_buf; | ||
3093 | __u32 data_offset, data_count; | 3093 | __u32 data_offset, data_count; |
3094 | char *end_of_smb; | 3094 | char *end_of_smb; |
3095 | 3095 | ||
@@ -3138,20 +3138,47 @@ CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon, | |||
3138 | goto qreparse_out; | 3138 | goto qreparse_out; |
3139 | } | 3139 | } |
3140 | end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount; | 3140 | end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount; |
3141 | reparse_buf = (struct reparse_data *) | 3141 | reparse_buf = (struct reparse_symlink_data *) |
3142 | ((char *)&pSMBr->hdr.Protocol + data_offset); | 3142 | ((char *)&pSMBr->hdr.Protocol + data_offset); |
3143 | if ((char *)reparse_buf >= end_of_smb) { | 3143 | if ((char *)reparse_buf >= end_of_smb) { |
3144 | rc = -EIO; | 3144 | rc = -EIO; |
3145 | goto qreparse_out; | 3145 | goto qreparse_out; |
3146 | } | 3146 | } |
3147 | if ((reparse_buf->PathBuffer + reparse_buf->PrintNameOffset + | 3147 | if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) { |
3148 | reparse_buf->PrintNameLength) > end_of_smb) { | 3148 | cifs_dbg(FYI, "NFS style reparse tag\n"); |
3149 | posix_buf = (struct reparse_posix_data *)reparse_buf; | ||
3150 | |||
3151 | if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) { | ||
3152 | cifs_dbg(FYI, "unsupported file type 0x%llx\n", | ||
3153 | le64_to_cpu(posix_buf->InodeType)); | ||
3154 | rc = -EOPNOTSUPP; | ||
3155 | goto qreparse_out; | ||
3156 | } | ||
3157 | is_unicode = true; | ||
3158 | sub_len = le16_to_cpu(reparse_buf->ReparseDataLength); | ||
3159 | if (posix_buf->PathBuffer + sub_len > end_of_smb) { | ||
3160 | cifs_dbg(FYI, "reparse buf beyond SMB\n"); | ||
3161 | rc = -EIO; | ||
3162 | goto qreparse_out; | ||
3163 | } | ||
3164 | *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer, | ||
3165 | sub_len, is_unicode, nls_codepage); | ||
3166 | goto qreparse_out; | ||
3167 | } else if (reparse_buf->ReparseTag != | ||
3168 | cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) { | ||
3169 | rc = -EOPNOTSUPP; | ||
3170 | goto qreparse_out; | ||
3171 | } | ||
3172 | |||
3173 | /* Reparse tag is NTFS symlink */ | ||
3174 | sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) + | ||
3175 | reparse_buf->PathBuffer; | ||
3176 | sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength); | ||
3177 | if (sub_start + sub_len > end_of_smb) { | ||
3149 | cifs_dbg(FYI, "reparse buf beyond SMB\n"); | 3178 | cifs_dbg(FYI, "reparse buf beyond SMB\n"); |
3150 | rc = -EIO; | 3179 | rc = -EIO; |
3151 | goto qreparse_out; | 3180 | goto qreparse_out; |
3152 | } | 3181 | } |
3153 | sub_start = reparse_buf->SubstituteNameOffset + reparse_buf->PathBuffer; | ||
3154 | sub_len = reparse_buf->SubstituteNameLength; | ||
3155 | if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) | 3182 | if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) |
3156 | is_unicode = true; | 3183 | is_unicode = true; |
3157 | else | 3184 | else |