@@ -5731,6 +5731,11 @@ static int smb2_get_info_file(struct ksmbd_work *work,
57315731 rc = buffer_check_err (le32_to_cpu (req -> OutputBufferLength ),
57325732 rsp , work -> response_buf );
57335733 ksmbd_fd_put (work , fp );
5734+
5735+ if (!rc )
5736+ rc = ksmbd_iov_pin_rsp (work , (void * )rsp ,
5737+ offsetof(struct smb2_query_info_rsp , Buffer ) +
5738+ le32_to_cpu (rsp -> OutputBufferLength ));
57345739 return rc ;
57355740}
57365741
@@ -5950,6 +5955,11 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
59505955 rc = buffer_check_err (le32_to_cpu (req -> OutputBufferLength ),
59515956 rsp , work -> response_buf );
59525957 path_put (& path );
5958+
5959+ if (!rc )
5960+ rc = ksmbd_iov_pin_rsp (work , (void * )rsp ,
5961+ offsetof(struct smb2_query_info_rsp , Buffer ) +
5962+ le32_to_cpu (rsp -> OutputBufferLength ));
59535963 return rc ;
59545964}
59555965
@@ -5963,13 +5973,15 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
59635973#else
59645974 struct user_namespace * user_ns ;
59655975#endif
5966- struct smb_ntsd * pntsd = ( struct smb_ntsd * ) rsp -> Buffer , * ppntsd = NULL ;
5976+ struct smb_ntsd * pntsd , * ppntsd = NULL ;
59675977 struct smb_fattr fattr = {{0 }};
59685978 struct inode * inode ;
59695979 __u32 secdesclen = 0 ;
59705980 unsigned int id = KSMBD_NO_FID , pid = KSMBD_NO_FID ;
59715981 int addition_info = le32_to_cpu (req -> AdditionalInformation );
5972- int rc = 0 , ppntsd_size = 0 ;
5982+ int rc = 0 , ppntsd_size = 0 , max_len ;
5983+ struct smb_ntsd * scratch ;
5984+ size_t scratch_len ;
59735985
59745986 if (addition_info & ~(OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO |
59755987 PROTECTED_DACL_SECINFO |
@@ -6030,23 +6042,44 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
60306042 fp -> filp -> f_path .dentry ,
60316043 & ppntsd );
60326044
6033- /* Check if sd buffer size exceeds response buffer size */
6034- if (smb2_resp_buf_len (work , 8 ) > ppntsd_size )
6045+ max_len = smb2_calc_max_out_buf_len (work ,
6046+ offsetof(struct smb2_query_info_rsp , Buffer ),
6047+ le32_to_cpu (req -> OutputBufferLength ));
6048+ if (max_len < 0 ) {
6049+ rc = - EINVAL ;
6050+ goto out ;
6051+ }
6052+
6053+ scratch_len = smb_acl_sec_desc_scratch_len (& fattr , ppntsd ,
6054+ ppntsd_size , addition_info );
6055+ pntsd = kvmalloc (scratch_len , KSMBD_DEFAULT_GFP );
6056+ if (!pntsd ) {
6057+ rc = - ENOMEM ;
6058+ goto out ;
6059+ }
6060+
60356061#if LINUX_VERSION_CODE >= KERNEL_VERSION (6 , 3 , 0 )
6036- rc = build_sec_desc (idmap , pntsd , ppntsd , ppntsd_size ,
6062+ rc = build_sec_desc (idmap , pntsd , ppntsd , ppntsd_size ,
6063+ addition_info , & secdesclen , & fattr );
60376064#else
6038- rc = build_sec_desc (user_ns , pntsd , ppntsd , ppntsd_size ,
6065+ rc = build_sec_desc (user_ns , pntsd , ppntsd , ppntsd_size ,
6066+ addition_info , & secdesclen , & fattr );
60396067#endif
6040- addition_info , & secdesclen , & fattr );
6068+
6069+ out :
60416070 posix_acl_release (fattr .cf_acls );
60426071 posix_acl_release (fattr .cf_dacls );
60436072 kfree (ppntsd );
60446073 ksmbd_fd_put (work , fp );
6045- if (rc )
6074+ if (rc ) {
6075+ kvfree (pntsd );
60466076 return rc ;
6077+ }
60476078
60486079 rsp -> OutputBufferLength = cpu_to_le32 (secdesclen );
6049- return 0 ;
6080+ return ksmbd_iov_pin_rsp_read (work , (void * )rsp ,
6081+ offsetof(struct smb2_query_info_rsp , Buffer ),
6082+ scratch , secdesclen );
60506083}
60516084
60526085/**
@@ -6069,6 +6102,9 @@ int smb2_query_info(struct ksmbd_work *work)
60696102 rc = - ENOMEM ;
60706103 goto err_out ;
60716104 }
6105+
6106+ rsp -> StructureSize = cpu_to_le16 (9 );
6107+ rsp -> OutputBufferOffset = cpu_to_le16 (72 );
60726108
60736109 switch (req -> InfoType ) {
60746110 case SMB2_O_INFO_FILE :
@@ -6090,14 +6126,6 @@ int smb2_query_info(struct ksmbd_work *work)
60906126 }
60916127 ksmbd_revert_fsids (work );
60926128
6093- if (!rc ) {
6094- rsp -> StructureSize = cpu_to_le16 (9 );
6095- rsp -> OutputBufferOffset = cpu_to_le16 (72 );
6096- rc = ksmbd_iov_pin_rsp (work , (void * )rsp ,
6097- offsetof(struct smb2_query_info_rsp , Buffer ) +
6098- le32_to_cpu (rsp -> OutputBufferLength ));
6099- }
6100-
61016129err_out :
61026130 if (rc < 0 ) {
61036131 if (rc == - EACCES )
@@ -6108,6 +6136,8 @@ int smb2_query_info(struct ksmbd_work *work)
61086136 rsp -> hdr .Status = STATUS_UNEXPECTED_IO_ERROR ;
61096137 else if (rc == - ENOMEM )
61106138 rsp -> hdr .Status = STATUS_INSUFFICIENT_RESOURCES ;
6139+ else if (rc == - EINVAL )
6140+ rsp -> hdr .Status = STATUS_INVALID_PARAMETER ;
61116141 else if (rc == - EOPNOTSUPP || rsp -> hdr .Status == 0 )
61126142 rsp -> hdr .Status = STATUS_INVALID_INFO_CLASS ;
61136143 smb2_set_err_rsp (work );
0 commit comments