]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: VFS: vfs_glusterfs. Protect vfs_gluster_fsync_done() from accessing a freed req...
authorJeremy Allison <jra@samba.org>
Sat, 29 Feb 2020 00:01:11 +0000 (16:01 -0800)
committerJeremy Allison <jra@samba.org>
Sun, 8 Mar 2020 18:07:44 +0000 (18:07 +0000)
If the fsp is forced closed by a SHUTDOWN_CLOSE whilst the
request is in flight (share forced closed by smbcontrol),
then we set state->req = NULL in the state destructor.

The existing state destructor prevents the state memory
from being freed, so when the thread completes and calls
vfs_gluster_fsync_done(), just throw away the result if
state->req == NULL.

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

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
source3/modules/vfs_glusterfs.c

index 4706e6f918971863c520c4dfb07badfbe9bd9cd4..b5300282b7b6eb4326a3f6e7648967a0d8bb3cbd 100644 (file)
@@ -1197,6 +1197,15 @@ static void vfs_gluster_fsync_do(void *private_data)
 
 static int vfs_gluster_fsync_state_destructor(struct vfs_gluster_fsync_state *state)
 {
+       /*
+        * This destructor only gets called if the request is still
+        * in flight, which is why we deny it by returning -1. We
+        * also set the req pointer to NULL so the _done function
+        * can detect the caller doesn't want the result anymore.
+        *
+        * Forcing the fsp closed by a SHUTDOWN_CLOSE can cause this.
+        */
+       state->req = NULL;
        return -1;
 }
 
@@ -1211,6 +1220,17 @@ static void vfs_gluster_fsync_done(struct tevent_req *subreq)
        TALLOC_FREE(subreq);
        SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes);
        talloc_set_destructor(state, NULL);
+       if (req == NULL) {
+               /*
+                * We were shutdown closed in flight. No one
+                * wants the result, and state has been reparented
+                * to the NULL context, so just free it so we
+                * don't leak memory.
+                */
+               DBG_NOTICE("gluster fsync request abandoned in flight\n");
+               TALLOC_FREE(state);
+               return;
+       }
        if (ret != 0) {
                if (ret != EAGAIN) {
                        tevent_req_error(req, ret);