]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Pipe: take a ref to existing while we are waiting 9238/head
authorSamuel Just <sjust@redhat.com>
Thu, 12 May 2016 23:57:49 +0000 (16:57 -0700)
committerNathan Cutler <ncutler@suse.com>
Mon, 27 Jun 2016 13:25:09 +0000 (15:25 +0200)
Otherwise, if it is reaped while we are waiting, it'll be a
use-after-free.

Fixes: http://tracker.ceph.com/issues/15870
Signed-off-by: Samuel Just <sjust@redhat.com>
(cherry picked from commit b224912d249453d754fc0478d3680f8cfa1a5c22)

Conflicts:
    src/msg/simple/Pipe.cc: nullptr changed to 0 because hammer is not compiled
    with -std=c++11

src/msg/simple/Pipe.cc

index ab277e08872c41b95d69f105bd8ff1616e743b31..1bc819a21e54ce6d85439f77a3bc5529ad7b918a 100644 (file)
@@ -479,13 +479,21 @@ int Pipe::accept()
         *  held by somebody trying to make use of the SimpleMessenger lock.
         *  So drop locks, wait, and retry. It just looks like a slow network
         *  to everybody else.
+        *
+        *  We take a ref to existing here since it might get reaped before we
+        *  wake up (see bug #15870).  We can be confident that it lived until
+        *  locked it since we held the msgr lock from _lookup_pipe through to
+        *  locking existing->lock and checking reader_dispatching.
         */
+       existing->get();
        pipe_lock.Unlock();
        msgr->lock.Unlock();
        existing->notify_on_dispatch_done = true;
        while (existing->reader_dispatching)
          existing->cond.Wait(existing->pipe_lock);
        existing->pipe_lock.Unlock();
+       existing->put();
+       existing = 0;
        goto retry_existing_lookup;
       }