Skip to content
Snippets Groups Projects
Commit ccc93e61 authored by Georgy Moshkin's avatar Georgy Moshkin :speech_balloon:
Browse files

fix: used to allow use after free in RPC handlers sometimes

parent 4ef47673
Branches
Tags
1 merge request!1308fix: RouteBuilder::register now only supports Fn, not FnMut
...@@ -6,6 +6,7 @@ use picoplugin::transport::rpc::server::FfiRpcHandler; ...@@ -6,6 +6,7 @@ use picoplugin::transport::rpc::server::FfiRpcHandler;
use picoplugin::util::RegionBuffer; use picoplugin::util::RegionBuffer;
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc;
use tarantool::error::BoxError; use tarantool::error::BoxError;
use tarantool::error::Error as TntError; use tarantool::error::Error as TntError;
use tarantool::error::TarantoolErrorCode; use tarantool::error::TarantoolErrorCode;
...@@ -54,8 +55,11 @@ pub fn proc_rpc_dispatch_impl(args: &RawBytes) -> Result<&'static RawBytes, TntE ...@@ -54,8 +55,11 @@ pub fn proc_rpc_dispatch_impl(args: &RawBytes) -> Result<&'static RawBytes, TntE
} }
}; };
// SAFETY: safe because keys don't leak // SAFETY: safe because
let maybe_handler = unsafe { handlers_mut().get(&key) }; // - keys don't leak
// - we don't hold on to a reference to the global data, and other fibers
// may safely mutate the HANDLERS hashmap.
let maybe_handler = unsafe { handlers_mut().get(&key).cloned() };
let Some(handler) = maybe_handler else { let Some(handler) = maybe_handler else {
#[rustfmt::skip] #[rustfmt::skip]
...@@ -103,7 +107,7 @@ pub fn proc_rpc_dispatch(args: &RawBytes) -> Result<&'static RawBytes, TntError> ...@@ -103,7 +107,7 @@ pub fn proc_rpc_dispatch(args: &RawBytes) -> Result<&'static RawBytes, TntError>
static mut HANDLERS: Option<RpcHandlerMap> = None; static mut HANDLERS: Option<RpcHandlerMap> = None;
type RpcHandlerMap = HashMap<RpcHandlerKey<'static>, FfiRpcHandler>; type RpcHandlerMap = HashMap<RpcHandlerKey<'static>, Rc<FfiRpcHandler>>;
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct RpcHandlerKey<'a> { struct RpcHandlerKey<'a> {
...@@ -194,7 +198,7 @@ pub fn register_rpc_handler(handler: FfiRpcHandler) -> Result<(), BoxError> { ...@@ -194,7 +198,7 @@ pub fn register_rpc_handler(handler: FfiRpcHandler) -> Result<(), BoxError> {
handler.version(), handler.version(),
handler.path(), handler.path(),
); );
entry.insert(handler); entry.insert(Rc::new(handler));
Ok(()) Ok(())
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment