-
Notifications
You must be signed in to change notification settings - Fork 116
I'm pretty sure you can cause UB in safe code with Callbacks #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
One thing to keep in mind is that callbacks must currently outlive the |
I think they can move capture a value mutably, then get a reference to themselves via Lua and cause some pretty bad juju right? I can at least see how to mutate a value I currently hold a &mut reference to. |
Ugh, of course. How could I miss that? Clearly I need to write more Rust. Demonstration of UB: extern crate rlua;
use rlua::*;
fn main() {
let lua = Lua::new();
let mut v = Some(Box::new(123));
let f = lua.create_function::<_, (), _>(move |lua, mutate: bool| {
if mutate {
v = None;
} else {
let r = v.as_mut().unwrap();
println!("BEFORE: first value at {:p}", r as *mut _);
println!("BEFORE: first value is {}", r);
lua.globals().get::<_, Function>("f").unwrap().call::<_, ()>(true).unwrap();
println!("AFTER: first value at {:p}", r as *mut _);
println!("AFTER: first value is {}", r);
}
Ok(())
});
lua.globals().set("f", f).unwrap();
lua.globals().get::<_, Function>("f").unwrap().call::<_, ()>(false).unwrap();
} Prints on my machine:
...and then segfaults |
Nice, thank you for the demonstration! Luckily, it should be a pretty easy fix. |
I think this is fixed now with 4b7a340. I know that this causes a panic, and not an error, and that that is not ideal. It's actually not hard to make it an error, but it really should be another Error enum entry, and the panic.. kind of matches what happens with resurrected userdata? I don't know, I could have made it an Error, and I actually will... I plan on working on fixing #38 really soon, and doing all the API breakage at once. |
Callbacks are not currently placed inside a RefCell, and are also FnMuts (not Fns), so if you call a callback inside itself, you've got mutability and aliasing.
I think all userdatas should be inside RefCell to ensure this problem is avoided in the future, we could also provide the ability to add Fn (not FnMut) callbacks, but it kind of doubles the API surface area, unless we do some trait trickery. I think just using RefCell is fine for the moment.
The text was updated successfully, but these errors were encountered: