CVE-2026-95834: Use after free in the kitty drag and drop protocol when a drag source item is aborted mid-transfer
Use After Free in the drag source path of the drag and drop protocol in kitty from 0.47.0 before 0.49.0 allows a program writing to the terminal to cause the terminal to read from and write to freed heap memory, because dragremotefiledata() in kitty/dnd.c holds a DragRemoteItem pointer into an array it does not own, calls topleveldatafordrag() or subdirdatafordrag(), and then continues to use that pointer. Those helpers, and addpayload() and populatedirentries() which they call, report errors through the abrt() macro, which expands to canceldrag() followed by a plain return, and canceldrag() calls dragfreeoffer(), which frees the array the pointer refers to. The helpers return void, so the caller receives no indication that the teardown happened, and proceeds to call allchildrencomplete() on the freed pointer, which dereferences it, and then to write through it. That dereference is guarded by a local flag that is set when the request carries no payload and announces no further data, which is the same condition that selects the finalisation block of addpayload(), so the error paths in that block reach it: a create that fails because an entry of the same name already exists, because the client may declare two entries with one name and the create operations use OCREAT with OEXCL and symlinkat(), a mkdirat() failure other than EEXIST, and the directory entry allocation paths. Both branches reach it. In the top level branch the caller's pointer is never cleared, so clearing the owning structure's own pointers during teardown does not help. In the sub directory branch subdirdatafordrag() sets the caller's pointer to NULL on entry and assigns it only after its own last error path, so its own aborts leave the caller with NULL and are stopped by a null check, but it then calls addpayload() with that pointer set, and an abort there leaves the caller holding a freed child node inside the item tree, which dragfreeoffer() frees by recursion. This results in undefined behaviour in the terminal process, reachable from the byte stream of any program running in the window.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
kittyto a version that resolves this vulnerability.Fixed in 0.49.0
Event History
Frequently Asked Questions
Which installations should be prioritized for remediation?
Kitty versions from 0.47.0 up to, but not including, 0.49.0 are affected. The issue is relevant where an untrusted or potentially malicious program can write to the terminal and can interact with the drag-and-drop drag-source path.
What conditions are required to trigger the flaw?
A program writing to the terminal must cause a drag source item to be aborted during a drag-and-drop transfer. The described reachable error paths include a failed create caused by an existing entry with the same name, together with a request carrying no payload and announcing no further data.
What should be done if the affected version is in use?
Move to kitty 0.49.0 or later, which is the first version outside the stated affected range. Until then, avoid allowing untrusted terminal-written content to initiate or control drag-and-drop transfers.