]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
neorados: Validate pointers from watch cookies
authorAdam Emerson <aemerson@redhat.com>
Thu, 7 Sep 2023 21:35:40 +0000 (17:35 -0400)
committerAdam Emerson <aemerson@redhat.com>
Thu, 7 Dec 2023 21:26:58 +0000 (16:26 -0500)
Since Objecter has a set used to validate pointers converted from
watch cookies before dereferencing them, expose a function to do so.

Also make the set a `std::unordered_set` since we use it for only this
purpose.

Signed-off-by: Adam Emerson <aemerson@redhat.com>
src/include/neorados/RADOS.hpp
src/neorados/RADOS.cc
src/osdc/Objecter.h

index ab95bdb17993ce631c5405c7dc56ab30fba27eac..dbc4aff3c5ac77a3fcee391c7b8af9f85c84e8d6 100644 (file)
@@ -494,9 +494,9 @@ public:
     return std::move(get_omap_vals_by_keys(keys, kv, ec));
   }
 
-  ReadOp& list_watchers(std::vector<struct ObjWatcher>* watchers,
+  ReadOp& list_watchers(std::vector<ObjWatcher>* watchers,
                        boost::system::error_code* ec = nullptr) &;
-  ReadOp&& list_watchers(std::vector<struct ObjWatcher>* watchers,
+  ReadOp&& list_watchers(std::vector<ObjWatcher>* watchers,
                         boost::system::error_code* ec = nullptr) && {
     return std::move(list_watchers(watchers, ec));
   }
@@ -1663,6 +1663,9 @@ public:
       }, consigned);
   }
 
+  tl::expected<ceph::timespan, boost::system::error_code>
+  check_watch(uint64_t cookie);
+
   using NotifySig = void(boost::system::error_code, ceph::buffer::list);
   using NotifyComp = boost::asio::any_completion_handler<NotifySig>;
   template<boost::asio::completion_token_for<NotifySig> CompletionToken>
@@ -1832,8 +1835,6 @@ private:
   void watch_(Object o, IOContext ioc,
              std::optional<std::chrono::seconds> timeout,
              WatchCB cb, WatchComp c);
-  tl::expected<ceph::timespan, boost::system::error_code>
-  watch_check_(uint64_t cookie);
   void notify_ack_(Object o, IOContext _ioc,
                   uint64_t notify_id,
                   uint64_t cookie,
index 9a71b1269a161d3e2802f4d397eb9dbf20fa4e4d..9b743f6e98624b56b9fb3ebb470a12b220c7c14a 100644 (file)
@@ -1375,10 +1375,14 @@ void RADOS::notify_ack_(Object o, IOContext _ioc,
                       nullptr, ioc->extra_op_flags, std::move(c));
 }
 
-tl::expected<ceph::timespan, bs::error_code> RADOS::watch_check_(uint64_t cookie)
+tl::expected<ceph::timespan, bs::error_code> RADOS::check_watch(uint64_t cookie)
 {
-  Objecter::LingerOp *linger_op = reinterpret_cast<Objecter::LingerOp*>(cookie);
-  return impl->objecter->linger_check(linger_op);
+  auto linger_op = reinterpret_cast<Objecter::LingerOp*>(cookie);
+  if (impl->objecter->is_valid_watch(linger_op)) {
+    return impl->objecter->linger_check(linger_op);
+  } else {
+    return tl::unexpected(bs::error_code(ENOTCONN, bs::generic_category()));
+  }
 }
 
 void RADOS::unwatch_(uint64_t cookie, IOContext _ioc,
index 201b7b62d08f86cecf41df22f46934bfbc2a1834..6daf57b928d3296a47c2c334978d679e8423c30e 100644 (file)
@@ -2532,7 +2532,7 @@ public:
 
   std::map<uint64_t, LingerOp*> linger_ops;
   // we use this just to confirm a cookie is valid before dereferencing the ptr
-  std::set<LingerOp*> linger_ops_set;
+  std::unordered_set<LingerOp*> linger_ops_set;
 
   std::map<ceph_tid_t,PoolStatOp*> poolstat_ops;
   std::map<ceph_tid_t,StatfsOp*> statfs_ops;
@@ -2614,6 +2614,12 @@ public:
   friend class CB_Objecter_GetVersion;
   friend class CB_DoWatchError;
 public:
+
+  bool is_valid_watch(LingerOp* op) {
+    std::shared_lock l(rwlock);
+    return linger_ops_set.contains(op);
+  }
+
   template<typename CT>
   auto linger_callback_flush(CT&& ct) {
     auto consigned = boost::asio::consign(