cybersecurity

Qubes OS QSB 118: When Filenames Become Commands

Qubes OS QSB 118: When Filenames Become Commands

Imagine sitting in dom0—the administrative domain that manages Qubes OS—and typing:

qvm-copy-to-vm work report.pdf

You expect a one-way transfer: a file leaves dom0 and arrives in the work qube. Yet the destination also sends a small status message back. In Qubes Security Bulletin 118, dated August 28, 2026 and published August 29, the Qubes team explains how that reply could turn an attacker-controlled filename into a command executed in dom0. (qubes-os.org)

The result is arbitrary command execution, meaning an attacker can make the operating system run commands of their choosing. That sounds alarming—and it is—but the attack has a specific shape. A qube must already be compromised, the user must start a copy from dom0 to that qube, and the transfer must reach the error-reporting path.

The boundary Qubes is designed to defend

Qubes OS uses security by compartmentalization. Applications run inside qubes, which are lightweight virtual machines isolated from one another. Dom0 sits at the center of the system with much higher privileges: it controls administration, manages other qubes, and is designed to have no ordinary network connection. The goal is that malware inside an app qube remains trapped there instead of reaching the system’s control plane. (doc.qubes-os.org)

Qubes still needs carefully controlled communication between those compartments. Its qrexec framework provides that communication by letting one domain request a service in another domain through a policy-controlled channel. A channel can be narrow and intentional while the data moving through it remains hostile. That distinction matters here: the transfer mechanism was not defeated by a malformed disk image or a hypervisor escape. A trusted component mishandled text received through an otherwise expected interface.

A copy operation has a return trip

The command involved is the special tool for copying files from dom0 to a VM:

qvm-copy-to-vm <target-qube> <file>

The file normally arrives in the target qube under /home/user/QubesIncoming/dom0/. From a user’s perspective, that is the whole story: select a destination, wait for the transfer, and open the file. (doc.qubes-os.org)

Behind the scenes, Qubes uses qfile, a compact file-transfer protocol with basic file metadata rather than the much larger feature set of formats such as tar. At the end of the transfer, the receiving side sends a confirmation containing a checksum—a short value used to detect transfer errors—along with an error code and the name of the last file it received. The filename is useful when a dialog needs to explain what went wrong, but it is also data supplied by the destination qube. (qubes-os.org)

That final detail created the opening.

The failure path was the trap

The vulnerability lived in error handling, not in the normal success path. The sequence looked like this:

  1. Dom0 received the filename from the target qube.
  2. A sanitizing function replaced control characters, non-ASCII characters, and double quotation marks.
  3. The cleaned name was inserted into a formatted error message.
  4. The dom0 error handler assembled a complete command string for a desktop dialog and passed it to system.

system is a standard C function that gives a command string to the operating system’s command shell. A shell does not see every character as ordinary text. It recognizes shell metacharacters—characters such as quote marks and command separators—as instructions that shape how a command is parsed.

The sanitizer used a blacklist that removed a few suspicious characters but left important shell syntax intact, including the single quote. The error handler also wrapped the complete dialog message in single quotes. A malicious filename could therefore close the surrounding quoted section and add shell syntax of its own. At that point, the filename was no longer merely displayed in an error dialog; part of it was interpreted as a command.

How can a filename become a command in Qubes OS? The answer is less mysterious than it first appears: an untrusted string crossed from data into shell syntax without a reliable code-and-data boundary. The bug was a classic command-injection mistake, placed in an unusual location—the backchannel used to report a failed file copy.

Why direct execution is safer

The safer design is to launch the dialog program directly and pass the message as one argument instead of building a shell command. In simplified pseudocode, that pattern looks like this:

argv = [
 '/usr/bin/kdialog',
 '--title', 'File copy/move error',
 '--sorry', dialog_message,
 NULL
]
execv(argv[0], argv)

Here, each array element is a separate process argument. Even if dialog_message contains punctuation that a shell normally treats as syntax, it remains one piece of text because no shell parses the array. This is the important difference between direct process execution and system.

The bulletin notes that the VM-side error-reporting implementation already followed this general approach. It used process creation followed by execlp to start zenity or kdialog, rather than handing a constructed command string to system. That variant was not affected by the same vulnerability. (qubes-os.org)

Escaping shell input can work when it is implemented perfectly, but avoiding the shell removes an entire class of mistakes. It also makes the intended interface clearer: the dialog text is an argument, not executable syntax.

The attack required a specific setup, but the impact was large

This was not an unauthenticated internet attack that reached every Qubes installation by itself. An attacker first needed control of a qube. The user then had to initiate qvm-copy-to-vm from dom0 to that compromised destination, and the malicious qube had to return a response that triggered the error path.

Those conditions still matter because Qubes is explicitly designed around the assumption that an app qube may become compromised while dom0 remains protected. Once an injected command runs in dom0, that assumption collapses. The Qubes security team states that successful exploitation can allow the attacker to take control of Qubes OS.

Patching Qubes OS

QSB 118 lists all Qubes OS releases as affected. For Qubes 4.3, the bulletin identifies qubes-core-dom0-linux version 4.3.22 as the security update for dom0. It instructs users to continue updating normally and says no special response is required beyond receiving the update. The package was initially moving from the security-testing repository toward the stable repository, so availability could depend on the update channel at the time.

Use the Qubes Update tool or its command-line equivalent rather than running a distribution package-manager update directly. For advanced users, the documentation lists:

sudo qubes-dom0-update

Qubes documentation warns that direct dnf or apt system updates can bypass built-in Qubes update protections. On a Qubes 4.3 system, the package named in the bulletin is the version to look for after updating. (doc.qubes-os.org)

The lesson beyond Qubes

Security bugs often hide in the paths developers touch least: warnings, cleanup code, progress messages, and failed operations. A filename may look harmless because it describes a file, but metadata is still attacker-controlled input when it comes from an untrusted system.

The durable lesson is not limited to Qubes OS. Do not treat error reporting as outside the security boundary. Avoid shell invocation when direct execution is available. Pass untrusted values as data, test failure paths with hostile input, and inspect every response field—not only the main payload.

A file copy that succeeds may look like a one-way operation. Its error message can travel in the opposite direction, carrying data that a privileged component must handle with the same care as any other input from a compromised machine.

ahsan

ahsan

Hello! I am Mr Ahsan, the writer of the Website. I am from Netherland. I like to write about technology and the news around it.

Comments (0)

No comments yet. Be the first to respond!

Leave a Comment

Your comment will be visible after review.