@@ -581,7 +581,7 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
581
581
rc = SMB2_ioctl (xid , tcon , NO_FILE_ID , NO_FILE_ID ,
582
582
FSCTL_QUERY_NETWORK_INTERFACE_INFO , true /* is_fsctl */ ,
583
583
NULL /* no data input */ , 0 /* no data input */ ,
584
- (char * * )& out_buf , & ret_data_len );
584
+ CIFSMaxBufSize , (char * * )& out_buf , & ret_data_len );
585
585
if (rc == - EOPNOTSUPP ) {
586
586
cifs_dbg (FYI ,
587
587
"server does not support query network interfaces\n" );
@@ -717,32 +717,28 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid)
717
717
oparms .fid -> mid = le64_to_cpu (o_rsp -> sync_hdr .MessageId );
718
718
#endif /* CIFS_DEBUG2 */
719
719
720
- if (o_rsp -> OplockLevel == SMB2_OPLOCK_LEVEL_LEASE )
721
- oplock = smb2_parse_lease_state (server , o_rsp ,
722
- & oparms .fid -> epoch ,
723
- oparms .fid -> lease_key );
724
- else
725
- goto oshr_exit ;
726
-
727
-
728
720
memcpy (tcon -> crfid .fid , pfid , sizeof (struct cifs_fid ));
729
721
tcon -> crfid .tcon = tcon ;
730
722
tcon -> crfid .is_valid = true;
731
723
kref_init (& tcon -> crfid .refcount );
732
- kref_get (& tcon -> crfid .refcount );
733
724
725
+ if (o_rsp -> OplockLevel == SMB2_OPLOCK_LEVEL_LEASE ) {
726
+ kref_get (& tcon -> crfid .refcount );
727
+ oplock = smb2_parse_lease_state (server , o_rsp ,
728
+ & oparms .fid -> epoch ,
729
+ oparms .fid -> lease_key );
730
+ } else
731
+ goto oshr_exit ;
734
732
735
733
qi_rsp = (struct smb2_query_info_rsp * )rsp_iov [1 ].iov_base ;
736
734
if (le32_to_cpu (qi_rsp -> OutputBufferLength ) < sizeof (struct smb2_file_all_info ))
737
735
goto oshr_exit ;
738
- rc = smb2_validate_and_copy_iov (
736
+ if (! smb2_validate_and_copy_iov (
739
737
le16_to_cpu (qi_rsp -> OutputBufferOffset ),
740
738
sizeof (struct smb2_file_all_info ),
741
739
& rsp_iov [1 ], sizeof (struct smb2_file_all_info ),
742
- (char * )& tcon -> crfid .file_all_info );
743
- if (rc )
744
- goto oshr_exit ;
745
- tcon -> crfid .file_all_info_is_valid = 1 ;
740
+ (char * )& tcon -> crfid .file_all_info ))
741
+ tcon -> crfid .file_all_info_is_valid = 1 ;
746
742
747
743
oshr_exit :
748
744
mutex_unlock (& tcon -> crfid .fid_mutex );
@@ -1299,7 +1295,7 @@ SMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon,
1299
1295
1300
1296
rc = SMB2_ioctl (xid , tcon , persistent_fid , volatile_fid ,
1301
1297
FSCTL_SRV_REQUEST_RESUME_KEY , true /* is_fsctl */ ,
1302
- NULL , 0 /* no input */ ,
1298
+ NULL , 0 /* no input */ , CIFSMaxBufSize ,
1303
1299
(char * * )& res_key , & ret_data_len );
1304
1300
1305
1301
if (rc ) {
@@ -1404,7 +1400,7 @@ smb2_ioctl_query_info(const unsigned int xid,
1404
1400
rc = SMB2_ioctl_init (tcon , & rqst [1 ],
1405
1401
COMPOUND_FID , COMPOUND_FID ,
1406
1402
qi .info_type , true, NULL ,
1407
- 0 );
1403
+ 0 , CIFSMaxBufSize );
1408
1404
}
1409
1405
} else if (qi .flags == PASSTHRU_QUERY_INFO ) {
1410
1406
memset (& qi_iov , 0 , sizeof (qi_iov ));
@@ -1532,8 +1528,8 @@ smb2_copychunk_range(const unsigned int xid,
1532
1528
rc = SMB2_ioctl (xid , tcon , trgtfile -> fid .persistent_fid ,
1533
1529
trgtfile -> fid .volatile_fid , FSCTL_SRV_COPYCHUNK_WRITE ,
1534
1530
true /* is_fsctl */ , (char * )pcchunk ,
1535
- sizeof (struct copychunk_ioctl ), ( char * * ) & retbuf ,
1536
- & ret_data_len );
1531
+ sizeof (struct copychunk_ioctl ), CIFSMaxBufSize ,
1532
+ ( char * * ) & retbuf , & ret_data_len );
1537
1533
if (rc == 0 ) {
1538
1534
if (ret_data_len !=
1539
1535
sizeof (struct copychunk_ioctl_rsp )) {
@@ -1693,7 +1689,7 @@ static bool smb2_set_sparse(const unsigned int xid, struct cifs_tcon *tcon,
1693
1689
rc = SMB2_ioctl (xid , tcon , cfile -> fid .persistent_fid ,
1694
1690
cfile -> fid .volatile_fid , FSCTL_SET_SPARSE ,
1695
1691
true /* is_fctl */ ,
1696
- & setsparse , 1 , NULL , NULL );
1692
+ & setsparse , 1 , CIFSMaxBufSize , NULL , NULL );
1697
1693
if (rc ) {
1698
1694
tcon -> broken_sparse_sup = true;
1699
1695
cifs_dbg (FYI , "set sparse rc = %d\n" , rc );
@@ -1766,7 +1762,7 @@ smb2_duplicate_extents(const unsigned int xid,
1766
1762
true /* is_fsctl */ ,
1767
1763
(char * )& dup_ext_buf ,
1768
1764
sizeof (struct duplicate_extents_to_file ),
1769
- NULL ,
1765
+ CIFSMaxBufSize , NULL ,
1770
1766
& ret_data_len );
1771
1767
1772
1768
if (ret_data_len > 0 )
@@ -1801,14 +1797,16 @@ smb3_set_integrity(const unsigned int xid, struct cifs_tcon *tcon,
1801
1797
true /* is_fsctl */ ,
1802
1798
(char * )& integr_info ,
1803
1799
sizeof (struct fsctl_set_integrity_information_req ),
1804
- NULL ,
1800
+ CIFSMaxBufSize , NULL ,
1805
1801
& ret_data_len );
1806
1802
1807
1803
}
1808
1804
1809
1805
/* GMT Token is @GMT-YYYY.MM.DD-HH.MM.SS Unicode which is 48 bytes + null */
1810
1806
#define GMT_TOKEN_SIZE 50
1811
1807
1808
+ #define MIN_SNAPSHOT_ARRAY_SIZE 16 /* See MS-SMB2 section 3.3.5.15.1 */
1809
+
1812
1810
/*
1813
1811
* Input buffer contains (empty) struct smb_snapshot array with size filled in
1814
1812
* For output see struct SRV_SNAPSHOT_ARRAY in MS-SMB2 section 2.2.32.2
@@ -1820,13 +1818,29 @@ smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon,
1820
1818
char * retbuf = NULL ;
1821
1819
unsigned int ret_data_len = 0 ;
1822
1820
int rc ;
1821
+ u32 max_response_size ;
1823
1822
struct smb_snapshot_array snapshot_in ;
1824
1823
1824
+ if (get_user (ret_data_len , (unsigned int __user * )ioc_buf ))
1825
+ return - EFAULT ;
1826
+
1827
+ /*
1828
+ * Note that for snapshot queries that servers like Azure expect that
1829
+ * the first query be minimal size (and just used to get the number/size
1830
+ * of previous versions) so response size must be specified as EXACTLY
1831
+ * sizeof(struct snapshot_array) which is 16 when rounded up to multiple
1832
+ * of eight bytes.
1833
+ */
1834
+ if (ret_data_len == 0 )
1835
+ max_response_size = MIN_SNAPSHOT_ARRAY_SIZE ;
1836
+ else
1837
+ max_response_size = CIFSMaxBufSize ;
1838
+
1825
1839
rc = SMB2_ioctl (xid , tcon , cfile -> fid .persistent_fid ,
1826
1840
cfile -> fid .volatile_fid ,
1827
1841
FSCTL_SRV_ENUMERATE_SNAPSHOTS ,
1828
1842
true /* is_fsctl */ ,
1829
- NULL , 0 /* no input data */ ,
1843
+ NULL , 0 /* no input data */ , max_response_size ,
1830
1844
(char * * )& retbuf ,
1831
1845
& ret_data_len );
1832
1846
cifs_dbg (FYI , "enum snaphots ioctl returned %d and ret buflen is %d\n" ,
@@ -2304,7 +2318,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
2304
2318
rc = SMB2_ioctl (xid , tcon , NO_FILE_ID , NO_FILE_ID ,
2305
2319
FSCTL_DFS_GET_REFERRALS ,
2306
2320
true /* is_fsctl */ ,
2307
- (char * )dfs_req , dfs_req_size ,
2321
+ (char * )dfs_req , dfs_req_size , CIFSMaxBufSize ,
2308
2322
(char * * )& dfs_rsp , & dfs_rsp_size );
2309
2323
} while (rc == - EAGAIN );
2310
2324
@@ -2658,7 +2672,8 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
2658
2672
rc = SMB2_ioctl_init (tcon , & rqst [num ++ ], cfile -> fid .persistent_fid ,
2659
2673
cfile -> fid .volatile_fid , FSCTL_SET_ZERO_DATA ,
2660
2674
true /* is_fctl */ , (char * )& fsctl_buf ,
2661
- sizeof (struct file_zero_data_information ));
2675
+ sizeof (struct file_zero_data_information ),
2676
+ CIFSMaxBufSize );
2662
2677
if (rc )
2663
2678
goto zero_range_exit ;
2664
2679
@@ -2735,7 +2750,8 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
2735
2750
rc = SMB2_ioctl (xid , tcon , cfile -> fid .persistent_fid ,
2736
2751
cfile -> fid .volatile_fid , FSCTL_SET_ZERO_DATA ,
2737
2752
true /* is_fctl */ , (char * )& fsctl_buf ,
2738
- sizeof (struct file_zero_data_information ), NULL , NULL );
2753
+ sizeof (struct file_zero_data_information ),
2754
+ CIFSMaxBufSize , NULL , NULL );
2739
2755
free_xid (xid );
2740
2756
return rc ;
2741
2757
}
0 commit comments