Contexte et vecteur d'attaque
Le composant qvm-copy-to-vm transfère des fichiers depuis dom0 vers une qube cible en utilisant le protocole qfile. Après le transfert, la qube renvoie un accusé de réception contenant un code d’erreur, un checksum et le nom du dernier fichier reçu. Si la qube est compromise, elle peut choisir le nom du fichier retourné. L’attaquant exploite alors ce nom pour injecter une commande dans dom0 lorsqu’une copie est déclenchée depuis l’interface graphique.
Mécanisme de la faille
Le traitement du nom de fichier s’effectue dans la fonction sanitize_remote_filename() du fichier linux-utils/qrexec-lib/pack.c. Cette fonction ne remplace que les caractères non‑ASCII et le guillemet double :
static void sanitize_remote_filename(char *untrusted_filename) {
for (; *untrusted_filename; ++untrusted_filename) {
if (*untrusted_filename < ' ' ||
*untrusted_filename > '~' ||
*untrusted_filename == '"')
*untrusted_filename = '_';
}
}
Les caractères de métashell (par exemple ;, `, $(…)) restent intacts. La fonction wait_for_result() transmet ensuite le nom « sanitisé » à call_error_handler(), qui construit une chaîne de commande pour l’affichage d’une boîte de dialogue. Le code concerné se trouve dans core-admin-linux/file-copy-vm/qfile-dom0-agent.c :
void display_error(const char *fmt, va_list args) {
char *dialog_cmd;
char buf[1024];
...
(void) vsnprintf(buf, sizeof(buf), fmt, args);
ret = stat("/usr/bin/kdialog", &st_buf);
#define KDIALOG_CMD "kdialog --title 'File copy/move error' --sorry "
#define ZENITY_CMD "zenity --title 'File copy/move error' --warning --text "
if (asprintf(&dialog_cmd, "%s '%s: %s (error type: %s)'",
ret==0 ? KDIALOG_CMD : ZENITY_CMD,
program_invocation_short_name, buf, strerror(errno)) < 0) {
fprintf(stderr, "Failed to allocate memory for error message :(");
return;
}
fprintf(stderr, "%s\n", buf);
system(dialog_cmd);
}
Le recours à system() lance le shell avec la chaîne construite. Le nom de fichier contrôlé par l’attaquant apparaît directement dans cette chaîne, ce qui permet l’exécution de toute commande shell.
Analyse des risques
Un attaquant qui a déjà compromis une qube peut, en déclenchant qvm-copy-to-vm depuis dom0, injecter une commande arbitraire dans le contexte de dom0. La commande s’exécute avec les privilèges de l’utilisateur qui a lancé la copie, généralement root dans dom0. La compromission de dom0 donne alors le contrôle total du système Qubes, y compris la capacité de manipuler les politiques de sécurité et d’accéder aux disques chiffrés. Tous les dépôts de QubesOS, y compris les versions antérieures, sont concernés, comme indiqué dans le bulletin de sécurité QSB‑118.
Correction et recommandations
Le correctif se trouve dans le paquet qubes-core-dom0-linux version 4.3.22, disponible pour Qubes 4.3. L’installation via l’outil Qubes Update ou la ligne de commande applique la mise à jour. Le correctif remplace l’appel à system() par une exécution directe de kdialog ou zenity avec des arguments pré‑échappés, éliminant ainsi la possibilité d’injection. En attendant la mise à jour, les utilisateurs peuvent désactiver temporairement les copies depuis dom0 vers des qubes non fiables ou vérifier manuellement le nom de fichier affiché avant toute opération. Le bulletin recommande de poursuivre les mises à jour normales, aucune action supplémentaire n’est requise.