aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsproto.h1
-rw-r--r--fs/cifs/cifssmb.c21
-rw-r--r--fs/cifs/inode.c5
3 files changed, 23 insertions, 4 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 7dd2f48a4073..4a4fd2dbca63 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -119,6 +119,7 @@ extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
119extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 119extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
120 const unsigned char *searchName, 120 const unsigned char *searchName,
121 FILE_ALL_INFO * findData, 121 FILE_ALL_INFO * findData,
122 int legacy /* whether to use old info level */,
122 const struct nls_table *nls_codepage, int remap); 123 const struct nls_table *nls_codepage, int remap);
123extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, 124extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
124 const unsigned char *searchName, 125 const unsigned char *searchName,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 79a01d35a783..6f50f2bc8870 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -2969,6 +2969,7 @@ int
2969CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 2969CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
2970 const unsigned char *searchName, 2970 const unsigned char *searchName,
2971 FILE_ALL_INFO * pFindData, 2971 FILE_ALL_INFO * pFindData,
2972 int legacy /* old style infolevel */,
2972 const struct nls_table *nls_codepage, int remap) 2973 const struct nls_table *nls_codepage, int remap)
2973{ 2974{
2974/* level 263 SMB_QUERY_FILE_ALL_INFO */ 2975/* level 263 SMB_QUERY_FILE_ALL_INFO */
@@ -3017,7 +3018,10 @@ QPathInfoRetry:
3017 byte_count = params + 1 /* pad */ ; 3018 byte_count = params + 1 /* pad */ ;
3018 pSMB->TotalParameterCount = cpu_to_le16(params); 3019 pSMB->TotalParameterCount = cpu_to_le16(params);
3019 pSMB->ParameterCount = pSMB->TotalParameterCount; 3020 pSMB->ParameterCount = pSMB->TotalParameterCount;
3020 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 3021 if(legacy)
3022 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
3023 else
3024 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3021 pSMB->Reserved4 = 0; 3025 pSMB->Reserved4 = 0;
3022 pSMB->hdr.smb_buf_length += byte_count; 3026 pSMB->hdr.smb_buf_length += byte_count;
3023 pSMB->ByteCount = cpu_to_le16(byte_count); 3027 pSMB->ByteCount = cpu_to_le16(byte_count);
@@ -3029,13 +3033,24 @@ QPathInfoRetry:
3029 } else { /* decode response */ 3033 } else { /* decode response */
3030 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3034 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3031 3035
3032 if (rc || (pSMBr->ByteCount < 40)) 3036 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3037 rc = -EIO;
3038 else if (!legacy && (pSMBr->ByteCount < 40))
3033 rc = -EIO; /* bad smb */ 3039 rc = -EIO; /* bad smb */
3040 else if(legacy && (pSMBr->ByteCount < 24))
3041 rc = -EIO; /* 24 or 26 expected but we do not read last field */
3034 else if (pFindData){ 3042 else if (pFindData){
3043 int size;
3035 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3044 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3045 if(legacy) /* we do not read the last field, EAsize, fortunately
3046 since it varies by subdialect and on Set vs. Get, is
3047 two bytes or 4 bytes depending but we don't care here */
3048 size = sizeof(FILE_INFO_STANDARD);
3049 else
3050 size = sizeof(FILE_ALL_INFO);
3036 memcpy((char *) pFindData, 3051 memcpy((char *) pFindData,
3037 (char *) &pSMBr->hdr.Protocol + 3052 (char *) &pSMBr->hdr.Protocol +
3038 data_offset, sizeof (FILE_ALL_INFO)); 3053 data_offset, size);
3039 } else 3054 } else
3040 rc = -ENOMEM; 3055 rc = -ENOMEM;
3041 } 3056 }
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 06dbce3a1815..fe6d21f99964 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -338,6 +338,7 @@ int cifs_get_inode_info(struct inode **pinode,
338 pfindData = (FILE_ALL_INFO *)buf; 338 pfindData = (FILE_ALL_INFO *)buf;
339 /* could do find first instead but this returns more info */ 339 /* could do find first instead but this returns more info */
340 rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData, 340 rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
341 0 /* not legacy */,
341 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 342 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
342 CIFS_MOUNT_MAP_SPECIAL_CHR); 343 CIFS_MOUNT_MAP_SPECIAL_CHR);
343 /* BB optimize code so we do not make the above call 344 /* BB optimize code so we do not make the above call
@@ -385,8 +386,10 @@ int cifs_get_inode_info(struct inode **pinode,
385 /* get new inode */ 386 /* get new inode */
386 if (*pinode == NULL) { 387 if (*pinode == NULL) {
387 *pinode = new_inode(sb); 388 *pinode = new_inode(sb);
388 if (*pinode == NULL) 389 if (*pinode == NULL) {
390 kfree(buf);
389 return -ENOMEM; 391 return -ENOMEM;
392 }
390 /* Is an i_ino of zero legal? Can we use that to check 393 /* Is an i_ino of zero legal? Can we use that to check
391 if the server supports returning inode numbers? Are 394 if the server supports returning inode numbers? Are
392 there other sanity checks we can use to ensure that 395 there other sanity checks we can use to ensure that