@@ -1118,6 +1118,86 @@ SMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon,
11181118 return rc ;
11191119}
11201120
1121+ static int
1122+ smb2_ioctl_query_info (const unsigned int xid ,
1123+ struct cifsFileInfo * file ,
1124+ unsigned long p )
1125+ {
1126+ struct cifs_tcon * tcon = tlink_tcon (file -> tlink );
1127+ struct cifs_ses * ses = tcon -> ses ;
1128+ char __user * arg = (char __user * )p ;
1129+ struct smb_query_info qi ;
1130+ struct smb_query_info __user * pqi ;
1131+ int rc = 0 ;
1132+ int flags = 0 ;
1133+ struct smb_rqst rqst ;
1134+ struct kvec iov [1 ];
1135+ struct kvec rsp_iov ;
1136+ int resp_buftype ;
1137+ struct smb2_query_info_rsp * rsp = NULL ;
1138+ void * buffer ;
1139+
1140+ if (copy_from_user (& qi , arg , sizeof (struct smb_query_info )))
1141+ return - EFAULT ;
1142+
1143+ if (qi .output_buffer_length > 1024 )
1144+ return - EINVAL ;
1145+
1146+ if (!ses || !(ses -> server ))
1147+ return - EIO ;
1148+
1149+ if (smb3_encryption_required (tcon ))
1150+ flags |= CIFS_TRANSFORM_REQ ;
1151+
1152+ buffer = kmalloc (qi .output_buffer_length , GFP_KERNEL );
1153+ if (buffer == NULL )
1154+ return - ENOMEM ;
1155+
1156+ if (copy_from_user (buffer , arg + sizeof (struct smb_query_info ),
1157+ qi .output_buffer_length )) {
1158+ kfree (buffer );
1159+ return - EFAULT ;
1160+ }
1161+
1162+ memset (& rqst , 0 , sizeof (struct smb_rqst ));
1163+ memset (& iov , 0 , sizeof (iov ));
1164+ rqst .rq_iov = iov ;
1165+ rqst .rq_nvec = 1 ;
1166+
1167+ rc = SMB2_query_info_init (tcon , & rqst , file -> fid .persistent_fid ,
1168+ file -> fid .volatile_fid ,
1169+ qi .file_info_class , qi .info_type ,
1170+ qi .additional_information ,
1171+ qi .input_buffer_length ,
1172+ qi .output_buffer_length , buffer );
1173+ kfree (buffer );
1174+ if (rc )
1175+ goto iqinf_exit ;
1176+
1177+ rc = cifs_send_recv (xid , ses , & rqst , & resp_buftype , flags , & rsp_iov );
1178+ rsp = (struct smb2_query_info_rsp * )rsp_iov .iov_base ;
1179+ if (rc )
1180+ goto iqinf_exit ;
1181+
1182+ pqi = (struct smb_query_info __user * )arg ;
1183+ if (le32_to_cpu (rsp -> OutputBufferLength ) < qi .input_buffer_length )
1184+ qi .input_buffer_length = le32_to_cpu (rsp -> OutputBufferLength );
1185+ if (copy_to_user (& pqi -> input_buffer_length , & qi .input_buffer_length ,
1186+ sizeof (qi .input_buffer_length ))) {
1187+ rc = - EFAULT ;
1188+ goto iqinf_exit ;
1189+ }
1190+ if (copy_to_user (pqi + 1 , rsp -> Buffer , qi .input_buffer_length )) {
1191+ rc = - EFAULT ;
1192+ goto iqinf_exit ;
1193+ }
1194+
1195+ iqinf_exit :
1196+ SMB2_query_info_free (& rqst );
1197+ free_rsp_buf (resp_buftype , rsp );
1198+ return rc ;
1199+ }
1200+
11211201static ssize_t
11221202smb2_copychunk_range (const unsigned int xid ,
11231203 struct cifsFileInfo * srcfile ,
@@ -1697,7 +1777,8 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
16971777 rc = SMB2_query_info_init (tcon , & rqst [1 ], COMPOUND_FID , COMPOUND_FID ,
16981778 FS_FULL_SIZE_INFORMATION ,
16991779 SMB2_O_INFO_FILESYSTEM , 0 ,
1700- sizeof (struct smb2_fs_full_size_info ));
1780+ sizeof (struct smb2_fs_full_size_info ), 0 ,
1781+ NULL );
17011782 if (rc )
17021783 goto qfs_exit ;
17031784 smb2_set_next_command (server , & rqst [1 ]);
@@ -3364,6 +3445,7 @@ struct smb_version_operations smb20_operations = {
33643445 .set_acl = set_smb2_acl ,
33653446#endif /* CIFS_ACL */
33663447 .next_header = smb2_next_header ,
3448+ .ioctl_query_info = smb2_ioctl_query_info ,
33673449};
33683450
33693451struct smb_version_operations smb21_operations = {
@@ -3459,6 +3541,7 @@ struct smb_version_operations smb21_operations = {
34593541 .set_acl = set_smb2_acl ,
34603542#endif /* CIFS_ACL */
34613543 .next_header = smb2_next_header ,
3544+ .ioctl_query_info = smb2_ioctl_query_info ,
34623545};
34633546
34643547struct smb_version_operations smb30_operations = {
@@ -3563,6 +3646,7 @@ struct smb_version_operations smb30_operations = {
35633646 .set_acl = set_smb2_acl ,
35643647#endif /* CIFS_ACL */
35653648 .next_header = smb2_next_header ,
3649+ .ioctl_query_info = smb2_ioctl_query_info ,
35663650};
35673651
35683652struct smb_version_operations smb311_operations = {
@@ -3668,6 +3752,7 @@ struct smb_version_operations smb311_operations = {
36683752 .set_acl = set_smb2_acl ,
36693753#endif /* CIFS_ACL */
36703754 .next_header = smb2_next_header ,
3755+ .ioctl_query_info = smb2_ioctl_query_info ,
36713756};
36723757
36733758struct smb_version_values smb20_values = {
0 commit comments