From 3a4dbc0a56a4df8569fb913359086195e1e50a5d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 27 Mar 2019 12:43:32 +0100 Subject: [PATCH 1/2] vfs_default: fix DEBUG messages in vfswrap_offload_write_*_done() SMB_VFS_{PREAD,PWRITE}_RECV() don't set errno, so we need to use strerror(aio_state.error) in the debug messages. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13862 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit 2abf9e9a95cbdf76109b3501dee3e0c34ad09194) --- source3/modules/vfs_default.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index ce5efd82a642..7b57e9c71f96 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -1797,7 +1797,7 @@ static void vfswrap_offload_write_read_done(struct tevent_req *subreq) nread = SMB_VFS_PREAD_RECV(subreq, &aio_state); TALLOC_FREE(subreq); if (nread == -1) { - DBG_ERR("read failed: %s\n", strerror(errno)); + DBG_ERR("read failed: %s\n", strerror(aio_state.error)); tevent_req_nterror(req, map_nt_error_from_unix(aio_state.error)); return; } @@ -1858,7 +1858,7 @@ static void vfswrap_offload_write_write_done(struct tevent_req *subreq) nwritten = SMB_VFS_PWRITE_RECV(subreq, &aio_state); TALLOC_FREE(subreq); if (nwritten == -1) { - DBG_ERR("write failed: %s\n", strerror(errno)); + DBG_ERR("write failed: %s\n", strerror(aio_state.error)); tevent_req_nterror(req, map_nt_error_from_unix(aio_state.error)); return; } -- 2.17.1 From 09dd9bf9edd08532a7ed14337a83ab917cc2fa97 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 31 Jul 2018 12:29:29 +0200 Subject: [PATCH 2/2] vfs_default: fix vfswrap_offload_write_send() NT_STATUS_INVALID_VIEW_SIZE check This fixes a regression introduced in commit 60e45a2d25401eaf9a15a86d19114670ccfde259, where the 'num' variable was renamed to 'to_copy', but a new 'num' variable was introduced. Note that off_t is signed! In future we need to watch out for filesystems supporting FMODE_UNSIGNED_OFFSET on Linux. Which means they use it unsigned. This is more or less a theoretical problem, The NT_STATUS_INVALID_PARAMETER cases are catched before by SMB_VFS_PREAD_SEND/RECV. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13862 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit 4d6cd932a955a99ca33cc4aedd7f612e56e0b1de) --- source3/modules/vfs_default.c | 43 ++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 7b57e9c71f96..7dfa335190c8 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -1630,6 +1630,8 @@ static struct tevent_req *vfswrap_offload_write_send( { struct tevent_req *req; struct vfswrap_offload_write_state *state = NULL; + /* off_t is signed! */ + off_t max_offset = INT64_MAX - to_copy; size_t num = MIN(to_copy, COPYCHUNK_MAX_TOTAL_LEN); files_struct *src_fsp = NULL; NTSTATUS status; @@ -1681,6 +1683,35 @@ static struct tevent_req *vfswrap_offload_write_send( return tevent_req_post(req, ev); } + if (state->src_off > max_offset) { + /* + * Protect integer checks below. + */ + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + if (state->src_off < 0) { + /* + * Protect integer checks below. + */ + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + if (state->dst_off > max_offset) { + /* + * Protect integer checks below. + */ + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + if (state->dst_off < 0) { + /* + * Protect integer checks below. + */ + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + status = vfs_offload_token_db_fetch_fsp(vfswrap_offload_ctx, token, &src_fsp); if (tevent_req_nterror(req, status)) { @@ -1704,17 +1735,12 @@ static struct tevent_req *vfswrap_offload_write_send( state->src_ev = src_fsp->conn->user_ev_ctx; state->src_fsp = src_fsp; - state->buf = talloc_array(state, uint8_t, num); - if (tevent_req_nomem(state->buf, req)) { - return tevent_req_post(req, ev); - } - status = vfs_stat_fsp(src_fsp); if (tevent_req_nterror(req, status)) { return tevent_req_post(req, ev); } - if (src_fsp->fsp_name->st.st_ex_size < state->src_off + num) { + if (src_fsp->fsp_name->st.st_ex_size < state->src_off + to_copy) { /* * [MS-SMB2] 3.3.5.15.6 Handling a Server-Side Data Copy Request * If the SourceOffset or SourceOffset + Length extends beyond @@ -1728,6 +1754,11 @@ static struct tevent_req *vfswrap_offload_write_send( return tevent_req_post(req, ev); } + state->buf = talloc_array(state, uint8_t, num); + if (tevent_req_nomem(state->buf, req)) { + return tevent_req_post(req, ev); + } + status = vfswrap_offload_write_loop(req); if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); -- 2.17.1