Skip to content

Commit 39d3201

Browse files
committed
Prevent XRc overflow when dropping RawLua with foreign Lua state
Calling `lua_close` triggers GC collection of the `ExtraData` that cascades to `RawLua::drop` where extra is already decremented to 0, causing a subtraction overflow.
1 parent 4aa6214 commit 39d3201

1 file changed

Lines changed: 6 additions & 3 deletions

File tree

src/state/raw.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::any::TypeId;
22
use std::cell::{Cell, UnsafeCell};
33
use std::ffi::CStr;
4-
use std::mem;
4+
use std::mem::{self, ManuallyDrop};
55
use std::os::raw::{c_char, c_int, c_void};
66
use std::panic::resume_unwind;
77
use std::ptr::{self, NonNull};
@@ -56,7 +56,7 @@ pub struct RawLua {
5656
// The state is dynamic and depends on context
5757
pub(super) state: Cell<*mut ffi::lua_State>,
5858
pub(super) main_state: Option<NonNull<ffi::lua_State>>,
59-
pub(super) extra: XRc<UnsafeCell<ExtraData>>,
59+
pub(super) extra: ManuallyDrop<XRc<UnsafeCell<ExtraData>>>,
6060
owned: bool,
6161
}
6262

@@ -82,6 +82,9 @@ impl Drop for RawLua {
8282
if !mem_state.is_null() {
8383
drop(Box::from_raw(mem_state));
8484
}
85+
86+
// Drop the `ExtraData` reference after `lua_close` has collected the registry entry
87+
ManuallyDrop::drop(&mut self.extra);
8588
}
8689
}
8790
}
@@ -245,7 +248,7 @@ impl RawLua {
245248
state: Cell::new(state),
246249
// Make sure that we don't store current state as main state (if it's not available)
247250
main_state: get_main_state(state).and_then(NonNull::new),
248-
extra: XRc::clone(&extra),
251+
extra: ManuallyDrop::new(XRc::clone(&extra)),
249252
owned,
250253
}));
251254
(*extra.get()).set_lua(&rawlua);

0 commit comments

Comments
 (0)