1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

smbd: use a DATA_BLOB and avoid data copy in delay_rename_for_lease_break()

in_input_buffer just points into the smbd_smb2_request iovecs data which is
guarenteed to have the same lifetime as the deferred rename processing, no need
to make a copy.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15608

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
This commit is contained in:
Ralph Boehme 2024-10-11 14:25:44 +02:00
parent a771506120
commit 00754add3c

View File

@ -173,16 +173,9 @@ struct defer_rename_state {
struct smbd_smb2_request *smb2req; struct smbd_smb2_request *smb2req;
struct tevent_context *ev; struct tevent_context *ev;
struct files_struct *fsp; struct files_struct *fsp;
char *data; DATA_BLOB data;
int data_size;
}; };
static int defer_rename_state_destructor(struct defer_rename_state *rename_state)
{
SAFE_FREE(rename_state->data);
return 0;
}
static void defer_rename_done(struct tevent_req *subreq); static void defer_rename_done(struct tevent_req *subreq);
struct delay_rename_lease_break_state { struct delay_rename_lease_break_state {
@ -232,9 +225,7 @@ static struct tevent_req *delay_rename_for_lease_break(struct tevent_req *req,
struct tevent_context *ev, struct tevent_context *ev,
struct files_struct *fsp, struct files_struct *fsp,
struct share_mode_lock *lck, struct share_mode_lock *lck,
char *data, DATA_BLOB *data)
int data_size)
{ {
struct tevent_req *subreq; struct tevent_req *subreq;
struct defer_rename_state *rename_state; struct defer_rename_state *rename_state;
@ -262,10 +253,7 @@ static struct tevent_req *delay_rename_for_lease_break(struct tevent_req *req,
rename_state->smb2req = smb2req; rename_state->smb2req = smb2req;
rename_state->ev = ev; rename_state->ev = ev;
rename_state->fsp = fsp; rename_state->fsp = fsp;
rename_state->data = data; rename_state->data = *data;
rename_state->data_size = data_size;
talloc_set_destructor(rename_state, defer_rename_state_destructor);
subreq = share_mode_watch_send( subreq = share_mode_watch_send(
rename_state, rename_state,
@ -329,11 +317,9 @@ static void defer_rename_done(struct tevent_req *subreq)
state->ev, state->ev,
state->fsp, state->fsp,
lck, lck,
state->data, &state->data);
state->data_size);
if (subreq) { if (subreq) {
/* Yep - keep waiting. */ /* Yep - keep waiting. */
state->data = NULL;
TALLOC_FREE(state); TALLOC_FREE(state);
TALLOC_FREE(lck); TALLOC_FREE(lck);
return; return;
@ -346,12 +332,11 @@ static void defer_rename_done(struct tevent_req *subreq)
SMB2_FILE_RENAME_INFORMATION_INTERNAL, SMB2_FILE_RENAME_INFORMATION_INTERNAL,
state->fsp, state->fsp,
state->fsp->fsp_name, state->fsp->fsp_name,
state->data, (char *)state->data.data,
state->data_size, state->data.length,
&ret_size); &ret_size);
TALLOC_FREE(lck); TALLOC_FREE(lck);
SAFE_FREE(state->data);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(state->req, status); tevent_req_nterror(state->req, status);
@ -406,11 +391,8 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx,
case SMB2_0_INFO_FILE: case SMB2_0_INFO_FILE:
{ {
uint16_t file_info_level; uint16_t file_info_level;
char *data;
int data_size;
int ret_size = 0; int ret_size = 0;
file_info_level = in_file_info_class + 1000; file_info_level = in_file_info_class + 1000;
if (file_info_level == SMB_FILE_RENAME_INFORMATION) { if (file_info_level == SMB_FILE_RENAME_INFORMATION) {
/* SMB2_FILE_RENAME_INFORMATION_INTERNAL == 0xFF00 + in_file_info_class */ /* SMB2_FILE_RENAME_INFORMATION_INTERNAL == 0xFF00 + in_file_info_class */
@ -466,23 +448,12 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx,
} }
} }
data = NULL;
data_size = in_input_buffer.length;
if (data_size > 0) {
data = (char *)SMB_MALLOC_ARRAY(char, data_size);
if (tevent_req_nomem(data, req)) {
return tevent_req_post(req, ev);
}
memcpy(data, in_input_buffer.data, data_size);
}
if (file_info_level == SMB2_FILE_RENAME_INFORMATION_INTERNAL) { if (file_info_level == SMB2_FILE_RENAME_INFORMATION_INTERNAL) {
struct tevent_req *subreq; struct tevent_req *subreq;
lck = get_existing_share_mode_lock(mem_ctx, lck = get_existing_share_mode_lock(mem_ctx,
fsp->file_id); fsp->file_id);
if (lck == NULL) { if (lck == NULL) {
SAFE_FREE(data);
tevent_req_nterror(req, tevent_req_nterror(req,
NT_STATUS_UNSUCCESSFUL); NT_STATUS_UNSUCCESSFUL);
return tevent_req_post(req, ev); return tevent_req_post(req, ev);
@ -493,8 +464,7 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx,
ev, ev,
fsp, fsp,
lck, lck,
data, &in_input_buffer);
data_size);
if (subreq) { if (subreq) {
/* Wait for lease break response. */ /* Wait for lease break response. */
@ -514,11 +484,10 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx,
file_info_level, file_info_level,
fsp, fsp,
fsp->fsp_name, fsp->fsp_name,
data, (char *)in_input_buffer.data,
data_size, in_input_buffer.length,
&ret_size); &ret_size);
TALLOC_FREE(lck); TALLOC_FREE(lck);
SAFE_FREE(data);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) { if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
status = NT_STATUS_INVALID_INFO_CLASS; status = NT_STATUS_INVALID_INFO_CLASS;