From b224912d249453d754fc0478d3680f8cfa1a5c22 Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Thu, 12 May 2016 16:57:49 -0700 Subject: [PATCH] Pipe: take a ref to existing while we are waiting 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 --- src/msg/simple/Pipe.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/msg/simple/Pipe.cc b/src/msg/simple/Pipe.cc index 53781b82b1735..35c3a249ad3f6 100644 --- a/src/msg/simple/Pipe.cc +++ b/src/msg/simple/Pipe.cc @@ -472,13 +472,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 = nullptr; goto retry_existing_lookup; }