mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
ksmbd: keep compound responses on query info errors
Do not reset the RFC1002 length of the complete response when a query
info buffer is too small. The current command will add its error response
through ksmbd_iov_pin_rsp(), while resetting the base length can truncate
earlier responses in a compound request.
This lets ksmbd return the earlier responses and the query-info error
response together. Remove the now-unused rsp_org parameter from the pipe
query-info helpers.
Fixes: e2b76ab8b5 ("ksmbd: add support for read compound")
Reported-by: Mobin Aydinfar <mobin@mobintestserver.ir>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit is contained in:
parent
f4fafaf021
commit
9fa26285ae
|
|
@ -6275,21 +6275,18 @@ int smb2_query_dir(struct ksmbd_work *work)
|
|||
* @reqOutputBufferLength: max buffer length expected in command response
|
||||
* @fixed_len: minimum fixed response length
|
||||
* @rsp: query info response buffer contains output buffer length
|
||||
* @rsp_org: base response buffer pointer in case of chained response
|
||||
*
|
||||
* Return: 0 on success, otherwise error
|
||||
*/
|
||||
static int buffer_check_err(int reqOutputBufferLength,
|
||||
unsigned int fixed_len,
|
||||
struct smb2_query_info_rsp *rsp,
|
||||
void *rsp_org)
|
||||
struct smb2_query_info_rsp *rsp)
|
||||
{
|
||||
unsigned int output_len = le32_to_cpu(rsp->OutputBufferLength);
|
||||
|
||||
if (reqOutputBufferLength < fixed_len) {
|
||||
pr_err("Invalid Buffer Size Requested\n");
|
||||
rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
*(__be32 *)rsp_org = cpu_to_be32(sizeof(struct smb2_hdr));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -6300,8 +6297,7 @@ static int buffer_check_err(int reqOutputBufferLength,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp,
|
||||
void *rsp_org)
|
||||
static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp)
|
||||
{
|
||||
struct smb2_file_standard_info *sinfo;
|
||||
|
||||
|
|
@ -6316,8 +6312,7 @@ static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp,
|
|||
cpu_to_le32(sizeof(struct smb2_file_standard_info));
|
||||
}
|
||||
|
||||
static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, u64 num,
|
||||
void *rsp_org)
|
||||
static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, u64 num)
|
||||
{
|
||||
struct smb2_file_internal_info *file_info;
|
||||
|
||||
|
|
@ -6331,8 +6326,7 @@ static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, u64 num,
|
|||
|
||||
static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
|
||||
struct smb2_query_info_req *req,
|
||||
struct smb2_query_info_rsp *rsp,
|
||||
void *rsp_org)
|
||||
struct smb2_query_info_rsp *rsp)
|
||||
{
|
||||
u64 id;
|
||||
int rc;
|
||||
|
|
@ -6357,16 +6351,16 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
|
|||
|
||||
switch (req->FileInfoClass) {
|
||||
case FILE_STANDARD_INFORMATION:
|
||||
get_standard_info_pipe(rsp, rsp_org);
|
||||
get_standard_info_pipe(rsp);
|
||||
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
|
||||
le32_to_cpu(rsp->OutputBufferLength),
|
||||
rsp, rsp_org);
|
||||
rsp);
|
||||
break;
|
||||
case FILE_INTERNAL_INFORMATION:
|
||||
get_internal_info_pipe(rsp, id, rsp_org);
|
||||
get_internal_info_pipe(rsp, id);
|
||||
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
|
||||
le32_to_cpu(rsp->OutputBufferLength),
|
||||
rsp, rsp_org);
|
||||
rsp);
|
||||
break;
|
||||
default:
|
||||
ksmbd_debug(SMB, "smb2_info_file_pipe for %u not supported\n",
|
||||
|
|
@ -7202,8 +7196,7 @@ static int smb2_get_info_file(struct ksmbd_work *work,
|
|||
if (test_share_config_flag(work->tcon->share_conf,
|
||||
KSMBD_SHARE_FLAG_PIPE)) {
|
||||
/* smb2 info file called for pipe */
|
||||
rc = smb2_get_info_file_pipe(work->sess, req, rsp,
|
||||
work->response_buf);
|
||||
rc = smb2_get_info_file_pipe(work->sess, req, rsp);
|
||||
goto iov_pin_out;
|
||||
}
|
||||
|
||||
|
|
@ -7321,7 +7314,7 @@ static int smb2_get_info_file(struct ksmbd_work *work,
|
|||
}
|
||||
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
|
||||
fixed_len,
|
||||
rsp, work->response_buf);
|
||||
rsp);
|
||||
}
|
||||
ksmbd_fd_put(work, fp);
|
||||
|
||||
|
|
@ -7592,7 +7585,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
|
|||
}
|
||||
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
|
||||
fixed_len,
|
||||
rsp, work->response_buf);
|
||||
rsp);
|
||||
path_put(&path);
|
||||
|
||||
if (!rc)
|
||||
|
|
@ -7706,7 +7699,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
|
|||
rsp->OutputBufferLength = cpu_to_le32(secdesclen);
|
||||
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
|
||||
le32_to_cpu(rsp->OutputBufferLength),
|
||||
rsp, work->response_buf);
|
||||
rsp);
|
||||
if (rc)
|
||||
goto err_out;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user