diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 184501e08b29..a9898e205f84 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -5486,7 +5486,6 @@ static int get_file_all_info(struct ksmbd_work *work, char *filename; u64 time; int ret, buf_free_len, filename_len; - struct smb2_query_info_req *req = ksmbd_req_buf_next(work); if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) { ksmbd_debug(SMB, "no right to read the attributes : 0x%x\n", @@ -5499,10 +5498,9 @@ static int get_file_all_info(struct ksmbd_work *work, return PTR_ERR(filename); filename_len = strlen(filename); - buf_free_len = smb2_calc_max_out_buf_len(work, + buf_free_len = smb2_resp_buf_len(work, offsetof(struct smb2_query_info_rsp, Buffer) + - offsetof(struct smb2_file_all_info, FileName), - le32_to_cpu(req->OutputBufferLength)); + offsetof(struct smb2_file_all_info, FileName)); if (buf_free_len < (filename_len + 1) * 2) { kfree(filename); return -EINVAL; @@ -5593,7 +5591,6 @@ static int get_file_stream_info(struct ksmbd_work *work, ssize_t xattr_list_len; int nbytes = 0, streamlen, stream_name_len, next, idx = 0; int buf_free_len; - struct smb2_query_info_req *req = ksmbd_req_buf_next(work); int ret; ret = vfs_getattr(&fp->filp->f_path, &stat, STATX_BASIC_STATS, @@ -5603,10 +5600,8 @@ static int get_file_stream_info(struct ksmbd_work *work, file_info = (struct smb2_file_stream_info *)rsp->Buffer; - buf_free_len = - smb2_calc_max_out_buf_len(work, - offsetof(struct smb2_query_info_rsp, Buffer), - le32_to_cpu(req->OutputBufferLength)); + buf_free_len = smb2_resp_buf_len(work, + offsetof(struct smb2_query_info_rsp, Buffer)); if (buf_free_len < 0) goto out; @@ -5919,6 +5914,7 @@ static int smb2_get_info_file(struct ksmbd_work *work, struct ksmbd_file *fp; int fileinfoclass = 0; int rc = 0; + unsigned int fixed_len; unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID; if (test_share_config_flag(work->tcon->share_conf, @@ -6022,10 +6018,23 @@ static int smb2_get_info_file(struct ksmbd_work *work, fileinfoclass); rc = -EOPNOTSUPP; } - if (!rc) + if (!rc) { + fixed_len = le32_to_cpu(rsp->OutputBufferLength); + switch (fileinfoclass) { + case FILE_ALL_INFORMATION: + fixed_len = FILE_ALL_INFORMATION_SIZE; + break; + case FILE_ALTERNATE_NAME_INFORMATION: + fixed_len = FILE_ALTERNATE_NAME_INFORMATION_SIZE; + break; + case FILE_STREAM_INFORMATION: + fixed_len = FILE_STREAM_INFORMATION_SIZE; + break; + } rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), - le32_to_cpu(rsp->OutputBufferLength), + fixed_len, rsp, work->response_buf); + } ksmbd_fd_put(work, fp); iov_pin_out: