Skip to content

Current __gc logic for userdata is unsound #19

Closed
@jonas-schievink

Description

@jonas-schievink

The manual states:

Moreover, if the finalizer marks a finalizing object for finalization again, its finalizer will be called again in the next cycle where the object is unreachable.

This means that a destructor assigned to the __gc metamethod might be run multiple times on the same userdata. Inside fn destructor, rlua currently just does this:

        let obj = &mut *(ffi::lua_touserdata(state, 1) as *mut T);
        mem::replace(obj, mem::uninitialized());
        0

If one figures out a way to resurrect the userdata object from within drop, this leads to a double free. However, I am not sure if this is possible, since all userdata must outlive 'static.

If this is by design, it would be helpful to document that. In general, rluas internals are barely documented which makes it hard to understand and debug stuff like #18.

EDIT: See comment below for use-after-free demonstration

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions