From 7df6a50b7fc80842cfead0f66b5c6c9106523b6a Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 17 Mar 2021 16:22:37 +0100 Subject: [PATCH 1/3] smbd: reset dangling watch_req pointer in poll_open_done We just freed subreq and a pointer to subreq is stored in open_rec->watch_req, so we must invalidate the pointer. Otherwise if the poll open timer fires it will do a TALLOC_FREE(open_rec->watch_req); on the dangling pointer which may crash or do something worse like freeing some other random talloc memory. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14672 CI: https://gitlab.com/samba-team/samba/-/merge_requests/1843 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 065ed088b3d5710c288e46a5bf1e063f9a29c8cc) --- source3/smbd/open.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index b82eb2f02b9..809bfdfd28f 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -3040,6 +3040,8 @@ static void poll_open_done(struct tevent_req *subreq) status = share_mode_watch_recv(subreq, NULL, NULL); TALLOC_FREE(subreq); + open_rec->watch_req = NULL; + DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n", nt_errstr(status)); -- 2.27.0 From 8231864c4c6446c560c7deaaaa443883201c977b Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 17 Mar 2021 16:24:28 +0100 Subject: [PATCH 2/3] smbd: cancel pending poll open timer in poll_open_done() The retry of the open is scheduled below, avoid rescheduling it a second time in the open retry timeout function. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14672 CI: https://gitlab.com/samba-team/samba/-/merge_requests/1843 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 171a58ff3e8ee07cf5d7af08eabcb4a7379e7ce5) --- source3/smbd/open.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 809bfdfd28f..87c14bb4367 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -3041,6 +3041,7 @@ static void poll_open_done(struct tevent_req *subreq) status = share_mode_watch_recv(subreq, NULL, NULL); TALLOC_FREE(subreq); open_rec->watch_req = NULL; + TALLOC_FREE(open_rec->te); DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n", nt_errstr(status)); -- 2.27.0 From 53a7c4a71b2933fb4df5b579370e6afeea4dfff4 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 16 Mar 2021 18:18:46 +0100 Subject: [PATCH 3/3] smbd: free open_rec state in remove_deferred_open_message_smb2_internal() The lifetime of open_rec (struct deferred_open_record) ojects is the time processing the SMB open request every time the request is scheduled, ie once we reschedule we must wipe the slate clean. In case the request gets deferred again, a new open_rec will be created by the schedule functions. This ensures any timer-event tied to the open_rec gets cancelled and doesn't fire unexpectedly. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14672 CI: https://gitlab.com/samba-team/samba/-/merge_requests/1843 RN: smbd panic when two clients open same file Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Thu Mar 18 18:04:09 UTC 2021 on sn-devel-184 (cherry picked from commit 591c9196962b695b01c0d86918b8f8a263e9665c) --- source3/smbd/smb2_create.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index 2dd3745dd32..8ff57c94aa0 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -1714,6 +1714,7 @@ static void remove_deferred_open_message_smb2_internal(struct smbd_smb2_request state->open_was_deferred = false; /* Ensure we don't have any outstanding immediate event. */ TALLOC_FREE(state->im); + TALLOC_FREE(state->open_rec); } void remove_deferred_open_message_smb2( -- 2.27.0