Skip to content

[windows] FlutterDesktopEnginePostPlatformThreadTask invokes on_cancel immediately when posting, then runs callback on the freed user_data (use-after-free) #193411

Closed

Description

@snowflysky

Steps to reproduce

This is a Windows engine/embedder bug, so the repro is native (C++) rather than Dart.

The attached app.zip is an unmodified flutter create --platforms=windows project plus this in windows/runner/flutter_window.cpp (FlutterWindow::OnCreate(), right before return true;):

std::thread([engine = flutter_controller_->engine()] {
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
engine->PostPlatformThreadTask([] {
// Never reached: the process dies inside (*cb)() before the task body runs.
std::fprintf(stderr, "[repro] task body ran\n");
});
}).detach();

flutter build windows --debug, then run build\windows\x64\runner\Debug\postplatformthreadtask_uaf.exe directly.
About ten seconds after the window appears, the process crashes with an access violation (exit code 0xC0000005 / -1073741819) while servicing the posted task — the task body ran line never prints (cdb capture in Logs; the delay is generous so flutter run can attach first — with a shorter delay flutter run may instead report "App failed to start" because the app dies before the tool attaches, which is the same crash).

Expected results

Per the API contract documented in flutter_windows.h:

// If the task is discarded without being executed (e.g. during engine
// shutdown), |on_cancel| is called on the platform thread so the caller can
// cleanup allocations. |on_cancel| can be nullptr if no cleanup is needed.

on_cancel should only ever run if a task is discarded without executing — never at post time, and never on the posting thread. In the repro, the task body should run on valid memory.

Actual results

  • on_cancel(user_data) is invoked synchronously, on the posting thread, inside the FlutterDesktopEnginePostPlatformThreadTask call.
  • The task is still queued and executed. With any on_cancel that releases user_data — the documented cleanup contract, and exactly what the shipped cpp_client_wrapper's FlutterEngine::PostPlatformThreadTask passes (delete user_data, cpp_client_wrapper/flutter_engine.cc) — the platform thread then invokes callback on freed memory. Every task posted through the official wrapper is a use-after-free, including on current master.
  • If the engine shuts down before the task runs, the heap-side Context destructor calls on_cancel a second time → double free.

Code sample

The complete repro project is attached as app.zip — an unmodified flutter create --platforms=windows app plus this addition in windows/runner/flutter_window.cpp (FlutterWindow::OnCreate()):

Addition to windows/runner/flutter_window.cpp
std::thread([engine = flutter_controller_->engine()] {
  std::this_thread::sleep_for(std::chrono::milliseconds(10000));
  engine->PostPlatformThreadTask([] {
    // Never reached: the process dies inside (*cb)() before the task body runs.
    std::fprintf(stderr, "[repro] task body ran\n");
  });
}).detach();

app.zip

Screenshots or Video

(None)

Logs

Crash under cdb — Flutter 3.47.5 stable, debug build, Windows 11 x64
(c03bc.bf060): Access violation - code c0000005 (!!! second chance !!!)
postplatformthreadtask_uaf!std::_Func_class<void>::operator()+0x35:
00007ff7`315469a5 488b00          mov     rax,qword ptr [rax] ds:feeefeee`feeefeee=????????????????

Child-SP          RetAddr               Call Site
0000002e`426ff5c0 00007ff7`31544187     postplatformthreadtask_uaf!std::_Func_class<void>::operator()+0x35 [functional @ 1057]
0000002e`426ff600 00007ff7`315441c6     postplatformthreadtask_uaf!<lambda_...>::operator()+0x47 [cpp_client_wrapper\flutter_engine.cc @ 134]
0000002e`426ff650 00007ffb`c1071ffe     postplatformthreadtask_uaf!<lambda_...>::<lambda_invoker_cdecl>+0x16
(Inline Function) --------`--------     flutter_windows!std::_Func_class<void>::operator()+0x1a [functional @ 874]
0000002e`426ff680 00007ffb`c1073e33     flutter_windows!flutter::TaskRunner::ProcessTasks+0x11c [task_runner.cc @ 55]
0000002e`426ff710 00007ffb`c1073f3b     flutter_windows!flutter::TaskRunnerWindow::ProcessTasks+0xa5 [task_runner_window.cc @ 181]
0000002e`426ff7b0 00007ffc`cf0452c6     flutter_windows!flutter::TaskRunnerWindow::HandleMessage+0x23 [task_runner_window.cc @ 226]
0000002e`426ff7e0 00007ffc`cf045d9d     USER32!CallWindowProcW+0x6a6
0000002e`426ff940 00007ff7`3153eef5     USER32!IsWindowUnicode+0x20d
0000002e`426ff9c0 00007ff7`31619152     postplatformthreadtask_uaf!wWinMain+0x235 [main.cpp @ 38]
[...CRT startup frames omitted...]

flutter_engine.cc @ 134 is the wrapper's callback thunk ((*cb)();), invoked from the engine's platform-thread task pump. The dereferenced pointer reads 0xFEEEFEEE, the Windows debug-heap free fill. We originally hit this in a production app (background native thread posting through FlutterEngine::PostPlatformThreadTask); its crash showed the same stack with the debug-CRT free fill 0xDDDDDDDDDDDDDDDD.

Flutter Doctor output

Doctor output
[√] Flutter (Channel stable, 3.47.5, on Microsoft Windows [Version 10.0.26300.9457], locale zh-CN)
    • Flutter version 3.47.5 on channel stable at <sdk path>
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 6a19cca564 (2026-09-17 14:13:22 -0400)
    • Engine revision af7e796e16
    • Dart version 3.13.4
    • DevTools version 2.60.0

[√] Windows Version (Windows 11 or higher, 26H2, 2009)

[√] Visual Studio - develop Windows apps (Visual Studio Community 2026 18.10.2)
    • Visual Studio Community 2026 version 18.10.12217.157
    • Windows 10 SDK version 10.0.28000.0

Activity

  1. Gustl22 commented on Sep 27, 2026

    @Gustl22
    Contributor

    Funny I just wanted to make the same report, and you were 30 minutes earlier :D
    here is my reproduction just for reference: https://github.com/Gustl22/flutter_issue_post_platform_thread_app

    I also already have a fix I can provide.

  2. puneetkukreja98 commented on Sep 28, 2026

    @puneetkukreja98
    Contributor

    @snowflysky Thanks for the report and the reproduction sample!

    I was able to reproduce the crash on Windows using the provided sample in debug mode (flutter build windows --debug). Running the executable resulted in an crash.

    Screen-shot:

    Image

    flutter doctor -v:

    [√] Flutter (Channel master, 3.49.0-1.0.pre-180, on Microsoft Windows [Version 10.0.26200.9168], locale en-IN) [2.7s]
        • Flutter version 3.49.0-1.0.pre-180 on channel master at C:\Developer\flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision a89783e103 (2 hours ago), 2026-09-28 08:00:15 +0000
        • Engine revision 31a2ab8801
        • Dart version 3.14.0 (build 3.14.0-271.0.dev)
        • DevTools version 2.61.0-dev.0
        • Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android,
          enable-ios, cli-animations, enable-native-assets, enable-record-use, enable-swift-package-manager,
          omit-legacy-version-file, enable-lldb-debugging, enable-uiscene-migration, enable-riscv64, enable-hcpp
    
    [√] Windows Version (Windows 11 or higher, 25H2, 2009) [1,797ms]
    
    [√] Android toolchain - develop for Android devices (Android SDK version 37.0.0) [3.1s]
        • Android SDK at C:\Users\Puneet\AppData\Local\Android\sdk
        • Emulator version 36.6.11.0 (build_id 15507667) (CL:N/A)
        • Platform android-37.1, build-tools 37.0.0
        • Java binary at: C:\Program Files\Android\Android Studio1\jbr\bin\java
          This is the JDK bundled with the latest Android Studio installation on this machine.
          To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
        • Java version OpenJDK Runtime Environment (build 21.0.10+-14961533-b1163.108)
        • All Android licenses accepted.
    
    [√] Chrome - develop for the web [105ms]
        • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe
    
    [√] Visual Studio - develop Windows apps (Visual Studio Community 2026 18.3.2) [104ms]
        • Visual Studio at C:\Program Files\Microsoft Visual Studio\18\Community
        • Visual Studio Community 2026 version 18.3.11520.95
        • Windows 10 SDK version 10.0.26100.0
    
    [√] Connected device (3 available) [293ms]
        • Windows (desktop) • windows • windows-x64    • Microsoft Windows [Version 10.0.26200.9168]
        • Chrome (web)      • chrome  • web-javascript • Google Chrome 153.0.8010.53
        • Edge (web)        • edge    • web-javascript • Microsoft Edge 154.0.4258.37
    
    [√] Network resources [603ms]
        • All expected network resources are available.
    
    • No issues found!
  3. added
    platform-windowsBuilding on or for Windows specifically
    c: fatal crashCrashes that terminate the process
    team-windowsOwned by the Windows platform team
    and removed
    in triagePresently being triaged by the triage team
    on Sep 28, 2026
  4. added
    P1High-priority issues at the top of the work list
    triaged-windowsTriaged by the Windows platform team
    on Oct 7, 2026
  5. added a commit that references this issue on Oct 8, 2026
    eb4d6c1
  6. github-actions commented on Oct 22, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  7. locked as resolved and limited conversation to collaborators on Oct 22, 2026
  8. added a commit that references this issue on Oct 29, 2026
    094e0a2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority issues at the top of the work listc: fatal crashCrashes that terminate the processplatform-windowsBuilding on or for Windows specificallyteam-windowsOwned by the Windows platform teamtriaged-windowsTriaged by the Windows platform team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions