Skip to content

Crash due to double free of OLE VARIANT data #3867

@nvaccessAuto

Description

@nvaccessAuto

Reported by mdcurran on 2014-02-10 04:20
NVDA can crash when a ctypes callback wrapping a Python function returns, if the ctypes callback is declaired to have a VARIANT as an in parameter. In NVDA, so far this only happens for IUIAutomationPropertyChangedEventHandler::HandlePropertyChangedEvent.
Practically speaking, this is on Windows 8 when NVDA's log viewer is opened, and log level is set to input/output, and the user types keyboard input.
It has also been seen in windbg.
Though due to Windows OLE internal memory caching, the data in the richEdit field must be around 7000 characters or larger.

The problem is specifically a bug shared between comtypes's VARIANT implementation, and ctypes callbacks.
As ctypes does not convert a VARIANT to one of its simple Pythonic types (int, string etc), it creates a new VARIANT object and copies the existing stack memory into the VARIANT. But when the VARIANT python object is deleted, its del calls VariantClear, freeing the data the variant is holding. Yet, The caller of the callback, e.g. a Windows RPC stub, also calls VariantClear, thus causing the double free.
This will most likely will be rather tricky to fix in comtypes/ctypes as it shows up a limitation in the ctypes extention module itself, namely that a Python object can't tell if it was initialized for a callback or not.

For now, for any VARIANT given as an in parameter, we can manually set its vt member to VT_EMPTY within the callback, thus stopping the VariantClear on object deletion. Windows RPC or any other caller will still be able to call VariantClear on the original stack memory.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions