Skip to content

desktop_drop: fix use-after-free when posting Windows platform tasks - #526

Merged
boyan01 merged 1 commit into
mainfrom
desktop_drop-windows-post-task-uaf
Oct 17, 2026
Merged

boyan01 merged 1 commit into
mainfrom
desktop_drop-windows-post-task-uaf

Conversation

@boyan01

@boyan01 boyan01 commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

Problem

FlutterDesktopEnginePostPlatformThreadTask in current stable Flutter (checked 3.47.7) builds its task context from a temporary:

auto context = std::make_shared<Context>(Context{callback, on_cancel, user_data});

The temporary's destructor sees invoked == false and calls on_cancel immediately. Our on_cancel deletes the queued std::function, so when the task runs, the callback reads freed memory and then deletes it a second time.

This happens on every FfiTransport::Post on Windows: every Dart -> native call (including initialize when a DropTarget mounts) and every native -> Dart reply. desktop_drop 0.9.0 crashes on Windows at startup.

Upstream fixed this in flutter/flutter#193412 (constructs Context in place and disallows copies). It is not in the current stable release yet.

Fix

Pass nullptr as on_cancel and let the callback own the task. This works on both the affected and the fixed engines. The trade-off: a task the engine discards at shutdown leaks instead of being freed. desktop_webview_window uses the same workaround.

Verification (Windows, Flutter 3.47.7, Debug)

  • flutter test: 23 tests passed.
  • example Debug build succeeded.
  • Launched the example on the interactive desktop:
    • origin/main: crashes right after startup, 0xC0000005 in desktop_drop_plugin.dll (APPCRASH event 1000).
    • This branch: still running after 20s, no crash events.

Not covered: real drag-and-drop on Windows (no Windows integration scenarios exist for this package), and the engine-shutdown path.

FlutterDesktopEnginePostPlatformThreadTask in current stable Flutter builds its
task context from a temporary whose destructor invokes on_cancel right away,
so the plugin freed each queued FFI task before it ran and freed it again
afterwards. This affected every Dart -> native call and every native -> Dart
reply on Windows.

Pass no on_cancel and let the callback own the task. The engine is fixed
upstream in flutter/flutter#193412; until the minimum Flutter version includes
it, a task discarded at engine shutdown leaks instead.
@boyan01
boyan01 merged commit 9293d2d into main Oct 17, 2026
7 checks passed
@boyan01
boyan01 deleted the desktop_drop-windows-post-task-uaf branch October 17, 2026 02:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant