@@ -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" );
@@ -1297,7 +1297,7 @@ SMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon,
1297
1297
1298
1298
rc = SMB2_ioctl (xid , tcon , persistent_fid , volatile_fid ,
1299
1299
FSCTL_SRV_REQUEST_RESUME_KEY , true /* is_fsctl */ ,
1300
- NULL , 0 /* no input */ ,
1300
+ NULL , 0 /* no input */ , CIFSMaxBufSize ,
1301
1301
(char * * )& res_key , & ret_data_len );
1302
1302
1303
1303
if (rc ) {
@@ -1402,7 +1402,7 @@ smb2_ioctl_query_info(const unsigned int xid,
1402
1402
rc = SMB2_ioctl_init (tcon , & rqst [1 ],
1403
1403
COMPOUND_FID , COMPOUND_FID ,
1404
1404
qi .info_type , true, NULL ,
1405
- 0 );
1405
+ 0 , CIFSMaxBufSize );
1406
1406
}
1407
1407
} else if (qi .flags == PASSTHRU_QUERY_INFO ) {
1408
1408
memset (& qi_iov , 0 , sizeof (qi_iov ));
@@ -1530,8 +1530,8 @@ smb2_copychunk_range(const unsigned int xid,
1530
1530
rc = SMB2_ioctl (xid , tcon , trgtfile -> fid .persistent_fid ,
1531
1531
trgtfile -> fid .volatile_fid , FSCTL_SRV_COPYCHUNK_WRITE ,
1532
1532
true /* is_fsctl */ , (char * )pcchunk ,
1533
- sizeof (struct copychunk_ioctl ), ( char * * ) & retbuf ,
1534
- & ret_data_len );
1533
+ sizeof (struct copychunk_ioctl ), CIFSMaxBufSize ,
1534
+ ( char * * ) & retbuf , & ret_data_len );
1535
1535
if (rc == 0 ) {
1536
1536
if (ret_data_len !=
1537
1537
sizeof (struct copychunk_ioctl_rsp )) {
@@ -1691,7 +1691,7 @@ static bool smb2_set_sparse(const unsigned int xid, struct cifs_tcon *tcon,
1691
1691
rc = SMB2_ioctl (xid , tcon , cfile -> fid .persistent_fid ,
1692
1692
cfile -> fid .volatile_fid , FSCTL_SET_SPARSE ,
1693
1693
true /* is_fctl */ ,
1694
- & setsparse , 1 , NULL , NULL );
1694
+ & setsparse , 1 , CIFSMaxBufSize , NULL , NULL );
1695
1695
if (rc ) {
1696
1696
tcon -> broken_sparse_sup = true;
1697
1697
cifs_dbg (FYI , "set sparse rc = %d\n" , rc );
@@ -1764,7 +1764,7 @@ smb2_duplicate_extents(const unsigned int xid,
1764
1764
true /* is_fsctl */ ,
1765
1765
(char * )& dup_ext_buf ,
1766
1766
sizeof (struct duplicate_extents_to_file ),
1767
- NULL ,
1767
+ CIFSMaxBufSize , NULL ,
1768
1768
& ret_data_len );
1769
1769
1770
1770
if (ret_data_len > 0 )
@@ -1799,14 +1799,16 @@ smb3_set_integrity(const unsigned int xid, struct cifs_tcon *tcon,
1799
1799
true /* is_fsctl */ ,
1800
1800
(char * )& integr_info ,
1801
1801
sizeof (struct fsctl_set_integrity_information_req ),
1802
- NULL ,
1802
+ CIFSMaxBufSize , NULL ,
1803
1803
& ret_data_len );
1804
1804
1805
1805
}
1806
1806
1807
1807
/* GMT Token is @GMT-YYYY.MM.DD-HH.MM.SS Unicode which is 48 bytes + null */
1808
1808
#define GMT_TOKEN_SIZE 50
1809
1809
1810
+ #define MIN_SNAPSHOT_ARRAY_SIZE 16 /* See MS-SMB2 section 3.3.5.15.1 */
1811
+
1810
1812
/*
1811
1813
* Input buffer contains (empty) struct smb_snapshot array with size filled in
1812
1814
* For output see struct SRV_SNAPSHOT_ARRAY in MS-SMB2 section 2.2.32.2
@@ -1818,13 +1820,29 @@ smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon,
1818
1820
char * retbuf = NULL ;
1819
1821
unsigned int ret_data_len = 0 ;
1820
1822
int rc ;
1823
+ u32 max_response_size ;
1821
1824
struct smb_snapshot_array snapshot_in ;
1822
1825
1826
+ if (get_user (ret_data_len , (unsigned int __user * )ioc_buf ))
1827
+ return - EFAULT ;
1828
+
1829
+ /*
1830
+ * Note that for snapshot queries that servers like Azure expect that
1831
+ * the first query be minimal size (and just used to get the number/size
1832
+ * of previous versions) so response size must be specified as EXACTLY
1833
+ * sizeof(struct snapshot_array) which is 16 when rounded up to multiple
1834
+ * of eight bytes.
1835
+ */
1836
+ if (ret_data_len == 0 )
1837
+ max_response_size = MIN_SNAPSHOT_ARRAY_SIZE ;
1838
+ else
1839
+ max_response_size = CIFSMaxBufSize ;
1840
+
1823
1841
rc = SMB2_ioctl (xid , tcon , cfile -> fid .persistent_fid ,
1824
1842
cfile -> fid .volatile_fid ,
1825
1843
FSCTL_SRV_ENUMERATE_SNAPSHOTS ,
1826
1844
true /* is_fsctl */ ,
1827
- NULL , 0 /* no input data */ ,
1845
+ NULL , 0 /* no input data */ , max_response_size ,
1828
1846
(char * * )& retbuf ,
1829
1847
& ret_data_len );
1830
1848
cifs_dbg (FYI , "enum snaphots ioctl returned %d and ret buflen is %d\n" ,
@@ -2302,7 +2320,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
2302
2320
rc = SMB2_ioctl (xid , tcon , NO_FILE_ID , NO_FILE_ID ,
2303
2321
FSCTL_DFS_GET_REFERRALS ,
2304
2322
true /* is_fsctl */ ,
2305
- (char * )dfs_req , dfs_req_size ,
2323
+ (char * )dfs_req , dfs_req_size , CIFSMaxBufSize ,
2306
2324
(char * * )& dfs_rsp , & dfs_rsp_size );
2307
2325
} while (rc == - EAGAIN );
2308
2326
@@ -2656,7 +2674,8 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
2656
2674
rc = SMB2_ioctl_init (tcon , & rqst [num ++ ], cfile -> fid .persistent_fid ,
2657
2675
cfile -> fid .volatile_fid , FSCTL_SET_ZERO_DATA ,
2658
2676
true /* is_fctl */ , (char * )& fsctl_buf ,
2659
- sizeof (struct file_zero_data_information ));
2677
+ sizeof (struct file_zero_data_information ),
2678
+ CIFSMaxBufSize );
2660
2679
if (rc )
2661
2680
goto zero_range_exit ;
2662
2681
@@ -2733,7 +2752,8 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
2733
2752
rc = SMB2_ioctl (xid , tcon , cfile -> fid .persistent_fid ,
2734
2753
cfile -> fid .volatile_fid , FSCTL_SET_ZERO_DATA ,
2735
2754
true /* is_fctl */ , (char * )& fsctl_buf ,
2736
- sizeof (struct file_zero_data_information ), NULL , NULL );
2755
+ sizeof (struct file_zero_data_information ),
2756
+ CIFSMaxBufSize , NULL , NULL );
2737
2757
free_xid (xid );
2738
2758
return rc ;
2739
2759
}
0 commit comments