From 947e4b63034fff2151f52c399a5d85925ea80911 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Mon, 18 Jul 2022 09:34:56 +0200 Subject: [PATCH] =?UTF-8?q?Don=E2=80=99t=20hold=20onto=20ReadOptions.inner?= =?UTF-8?q?=20when=20iterating=20(#655)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db_iterator.rs | 14 ++++++++------ src/db_options.rs | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/db_iterator.rs b/src/db_iterator.rs index fa988e6..d671470 100644 --- a/src/db_iterator.rs +++ b/src/db_iterator.rs @@ -72,10 +72,10 @@ pub type DBRawIterator<'a> = DBRawIteratorWithThreadMode<'a, DB>; pub struct DBRawIteratorWithThreadMode<'a, D: DBAccess> { inner: std::ptr::NonNull, - /// When iterate_upper_bound is set, the inner C iterator keeps a pointer to the upper bound - /// inside `_readopts`. Storing this makes sure the upper bound is always alive when the - /// iterator is being used. - _readopts: ReadOptions, + /// When iterate_upper_bound or iterate_lower_bound is set, the inner + /// C iterator keeps a pointer to the bounds. We need to hold onto those + /// slices or else C iterator ends up reading freed memory. + _bounds: (Option>, Option>), db: PhantomData<&'a D>, } @@ -96,15 +96,17 @@ impl<'a, D: DBAccess> DBRawIteratorWithThreadMode<'a, D> { Self::from_inner(inner, readopts) } - fn from_inner(inner: *mut ffi::rocksdb_iterator_t, readopts: ReadOptions) -> Self { + fn from_inner(inner: *mut ffi::rocksdb_iterator_t, mut readopts: ReadOptions) -> Self { // This unwrap will never fail since rocksdb_create_iterator and // rocksdb_create_iterator_cf functions always return non-null. They // use new and deference the result so any nulls would end up in SIGSEGV // there and we have bigger issue. let inner = std::ptr::NonNull::new(inner).unwrap(); + let lower = readopts.iterate_lower_bound.take(); + let upper = readopts.iterate_upper_bound.take(); Self { inner, - _readopts: readopts, + _bounds: (lower, upper), db: PhantomData, } } diff --git a/src/db_options.rs b/src/db_options.rs index d93a690..167e73e 100644 --- a/src/db_options.rs +++ b/src/db_options.rs @@ -336,8 +336,8 @@ pub struct BlockBasedOptions { pub struct ReadOptions { pub(crate) inner: *mut ffi::rocksdb_readoptions_t, - iterate_upper_bound: Option>, - iterate_lower_bound: Option>, + pub(crate) iterate_upper_bound: Option>, + pub(crate) iterate_lower_bound: Option>, } /// Configuration of cuckoo-based storage.