]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
osd/PG: do not touch this->cct after PG is destroyed
authorSage Weil <sage@redhat.com>
Mon, 4 Mar 2019 15:13:06 +0000 (09:13 -0600)
committerSage Weil <sage@redhat.com>
Mon, 4 Mar 2019 15:13:55 +0000 (09:13 -0600)
- thread A drops last second-to-last ref
- thread B drops last ref
- thread B deletes pg
- thread A does

  lgeneric_subdout(cct, refs, 1) << "PG::put " << this << " "
  ..

touching this->cct, a use-after-free that valgrind notices with

  <kind>InvalidRead</kind>
  <what>Invalid read of size 8</what>
  <stack>
    <frame>
      <ip>0x74ED34</ip>
      <obj>/usr/bin/ceph-osd</obj>
      <fn>PG::put(char const*)</fn>
      <dir>/usr/src/debug/ceph-14.1.0-283-g569f086/src/osd</dir>
      <file>PG.cc</file>
      <line>179</line>
    </frame>
    <frame>
      <ip>0x7C1E76</ip>
      <obj>/usr/bin/ceph-osd</obj>
      <fn>ContainerContext&lt;boost::intrusive_ptr&lt;PG&gt; &gt;::~ContainerContext()</fn>
      <dir>/usr/src/debug/ceph-14.1.0-283-g569f086/src/osd</dir>
      <file>PG.h</file>
      <line>566</line>
    </frame>
    <frame>
      <ip>0xC95675</ip>
      <obj>/usr/bin/ceph-osd</obj>
      <fn>Finisher::finisher_thread_entry()</fn>
      <dir>/usr/src/debug/ceph-14.1.0-283-g569f086/src/common</dir>
      <file>Finisher.cc</file>
      <line>67</line>
    </frame>
    <frame>
      <ip>0xD656E24</ip>
      <obj>/usr/lib64/libpthread-2.17.so</obj>
      <fn>start_thread</fn>
    </frame>
    <frame>
      <ip>0xE5B4BAC</ip>
      <obj>/usr/lib64/libc-2.17.so</obj>
      <fn>clone</fn>
    </frame>
  </stack>
  <auxwhat>Address 0x470b29e8 is 152 bytes inside a block of size 11,632 free'd</auxwhat>
  <stack>
  ...

Fixes: http://tracker.ceph.com/issues/38484
Signed-off-by: Sage Weil <sage@redhat.com>
src/osd/PG.cc

index 3e779341f82882c7ad43ec764dc15148b056aa0f..db6b22d90b7f2ec6d50530038ae8059e75f8d75a 100644 (file)
@@ -175,10 +175,12 @@ void PG::put(const char* tag)
     }
   }
 #endif
+  auto local_cct = cct;
   int after = --ref;
-  lgeneric_subdout(cct, refs, 5) << "PG::put " << this << " "
-                                << "tag " << (tag ? tag : "(none") << " "
-                                << (after + 1) << " -> " << after << dendl;
+  lgeneric_subdout(local_cct, refs, 5) << "PG::put " << this << " "
+                                      << "tag " << (tag ? tag : "(none") << " "
+                                      << (after + 1) << " -> " << after
+                                      << dendl;
   if (after == 0)
     delete this;
 }