Quickshell / partage KDE Connect : stabiliser le fichier validé jusqu’à sa prise en charge #18

Closed
opened 2026-10-24 13:10:05 +00:00 by mathieu · 3 comments
Owner

Risque conditionnel établi par le code

Dans mathieu/desktop-bridge.py:362–369, file.stat(), file.resolve() puis la lecture du shareUrl par KDE Connect utilisent des résolutions de chemin distinctes. Une entrée ou un répertoire remplaçable par un tiers peut changer entre validation et consommation.

Cela peut faire partager un autre fichier lisible par l’utilisateur, ou une cible non régulière malgré le contrôle initial. Précondition : un acteur peut remplacer le fichier ou un élément pertinent du chemin, notamment dans un répertoire partagé. Aucun transfert indu n’a été reproduit ; le comportement exact d’ouverture côté KDE Connect reste à vérifier.

Résultat attendu

Décision approuvée par Mathieu : faute de prise en charge sortante corrélée dans l’API KDE Connect vérifiée, retenir une copie privée avec quota/refus à capacité et nettoyage opportuniste dès24h. La durée est une politique conservatrice, pas une preuve de consommation ; un transfert au-delà de cette fenêtre reste un risque accepté et documenté.

Établir les garanties réelles de l’API KDE Connect puis lier l’objet validé au contenu pris en charge. Si une copie privée issue d’un descripteur validé est nécessaire, définir permissions, limites de taille, nettoyage et durée de vie jusqu’à la prise en charge effective. Un second stat() du même chemin ne ferme pas à lui seul la course.

Commencer par la solution la plus simple compatible avec ces garanties ; ne pas créer un service de transfert maison. Toute modification du comportement des liens symboliques doit être explicite.

Validation

  • Fichiers de démonstration remplacés entre validation/résolution et avant l’ouverture par un faux consommateur : jamais le contenu de remplacement.
  • Refuser les cibles non régulières ; gérer annulation, erreur et transfert différé sans fichier temporaire divulgué ou supprimé trop tôt.
  • Aucun accès à des fichiers privés réels ni partage avec un vrai téléphone lors des tests.

Articulation

Après le correctif de destinataire #14. Ce durcissement est distinct de celui-ci et demande une investigation du contrat de consommation.

Référence

Revue du code au commit 5e350a8, avec Quickshell 0.3.2. Les 18 suites existantes passent ; les cas ci-dessous complètent cette couverture. Chantier : #11.

  • with pi 🥧
## Risque conditionnel établi par le code Dans `mathieu/desktop-bridge.py:362–369`, `file.stat()`, `file.resolve()` puis la lecture du `shareUrl` par KDE Connect utilisent des résolutions de chemin distinctes. Une entrée ou un répertoire remplaçable par un tiers peut changer entre validation et consommation. Cela peut faire partager un autre fichier lisible par l’utilisateur, ou une cible non régulière malgré le contrôle initial. Précondition : un acteur peut remplacer le fichier ou un élément pertinent du chemin, notamment dans un répertoire partagé. Aucun transfert indu n’a été reproduit ; le comportement exact d’ouverture côté KDE Connect reste à vérifier. ## Résultat attendu **Décision approuvée par Mathieu :** faute de prise en charge sortante corrélée dans l’API KDE Connect vérifiée, retenir une copie privée avec quota/refus à capacité et nettoyage opportuniste dès24h. La durée est une politique conservatrice, pas une preuve de consommation ; un transfert au-delà de cette fenêtre reste un risque accepté et documenté. Établir les garanties réelles de l’API KDE Connect puis lier l’objet validé au contenu pris en charge. Si une copie privée issue d’un descripteur validé est nécessaire, définir permissions, limites de taille, nettoyage et durée de vie jusqu’à la prise en charge effective. Un second `stat()` du même chemin ne ferme pas à lui seul la course. Commencer par la solution la plus simple compatible avec ces garanties ; ne pas créer un service de transfert maison. Toute modification du comportement des liens symboliques doit être explicite. ## Validation - [x] Fichiers de démonstration remplacés entre validation/résolution et avant l’ouverture par un faux consommateur : jamais le contenu de remplacement. - [x] Refuser les cibles non régulières ; gérer annulation, erreur et transfert différé sans fichier temporaire divulgué ou supprimé trop tôt. - [x] Aucun accès à des fichiers privés réels ni partage avec un vrai téléphone lors des tests. ## Articulation Après le correctif de destinataire #14. Ce durcissement est distinct de celui-ci et demande une investigation du contrat de consommation. ## Référence Revue du code [au commit `5e350a8`](https://git.2027a.net/mathieu/dotfiles/src/commit/5e350a8945af99e6e6b1c7f472fb7529a26a1826/quickshell/), avec Quickshell 0.3.2. Les 18 suites existantes passent ; les cas ci-dessous complètent cette couverture. Chantier : #11. - with pi 🥧
Author
Owner

Investigation statique du tag KDE Connect installé v26.08.2 (commit 2a0a8c0cee6e2ae0c1ae842be9e1a9fb6cea2a69) : SharePlugin::shareUrl construit un QFile mais ne l’ouvre pas ; le backend LAN l’ouvre plus tard, après mise en file et connexion chiffrée du récepteur. Le retour D-Bus ne garantit donc pas que le chemin est déjà consommé. L’interface shareUrl est void, sans identifiant ni signal de fin sortante corrélé.

Sources officielles : shareUrl, interface, ouverture LAN. Pas de transfert réel, audit des patches distro ni introspection d’appareil. Outils web absents dans le rôle de recherche : le parent a fourni les sources de ce tag ; aucun changement de runner ou du projet pour l’investigation.

Le simple FD du helper ou la suppression d’une copie au retour de busctl ne conviennent pas. Une copie privée doit survivre au helper et à un dispatch incertain. Aucun TTL fini n’est une preuve de fin d’un transfert en file.

Décision demandée à Mathieu dans la conversation : accepter un cache privé avec quota/refus à capacité et nettoyage opportuniste après 24 h, en reconnaissant le risque d’échec pour une prise en charge exceptionnellement tardive ? Alternative : pas d’expiration automatique des copies potentiellement en attente, mais accumulation jusqu’à nettoyage explicite. Implémentation de cette politique en attente ; les travaux indépendants continuent.

  • with pi 🥧
Investigation statique du tag KDE Connect installé `v26.08.2` (commit `2a0a8c0cee6e2ae0c1ae842be9e1a9fb6cea2a69`) : `SharePlugin::shareUrl` construit un QFile mais ne l’ouvre pas ; le backend LAN l’ouvre plus tard, après mise en file et connexion chiffrée du récepteur. Le retour D-Bus ne garantit donc pas que le chemin est déjà consommé. L’interface `shareUrl` est `void`, sans identifiant ni signal de fin sortante corrélé. Sources officielles : [shareUrl](https://github.com/KDE/kdeconnect-kde/blob/2a0a8c0cee6e2ae0c1ae842be9e1a9fb6cea2a69/plugins/share/shareplugin.cpp#L241-L267), [interface](https://github.com/KDE/kdeconnect-kde/blob/2a0a8c0cee6e2ae0c1ae842be9e1a9fb6cea2a69/plugins/share/shareplugin.h#L20-L44), [ouverture LAN](https://github.com/KDE/kdeconnect-kde/blob/2a0a8c0cee6e2ae0c1ae842be9e1a9fb6cea2a69/core/backends/lan/uploadjob.cpp#L30-L60). Pas de transfert réel, audit des patches distro ni introspection d’appareil. Outils web absents dans le rôle de recherche : le parent a fourni les sources de ce tag ; aucun changement de runner ou du projet pour l’investigation. Le simple FD du helper ou la suppression d’une copie au retour de `busctl` ne conviennent pas. Une copie privée doit survivre au helper et à un dispatch incertain. Aucun TTL fini n’est une preuve de fin d’un transfert en file. **Décision demandée à Mathieu dans la conversation :** accepter un cache privé avec quota/refus à capacité et nettoyage opportuniste après 24 h, en reconnaissant le risque d’échec pour une prise en charge exceptionnellement tardive ? Alternative : pas d’expiration automatique des copies potentiellement en attente, mais accumulation jusqu’à nettoyage explicite. Implémentation de cette politique en attente ; les travaux indépendants continuent. - with pi 🥧
Author
Owner

Mathieu a explicitement validé dans la conversation le cache privé avec quota et nettoyage opportuniste après24h. Le TTL est une politique de conservation, pas une preuve de consommation KDE Connect ; aucune suppression au retour de busctl/timeout ou arrêt du bridge. Implémentation isolée et tests synthétiques démarrent ; pas de vrai partage.

  • with pi 🥧
Mathieu a explicitement validé dans la conversation le cache privé avec quota et nettoyage opportuniste après24h. Le TTL est une politique de conservation, pas une preuve de consommation KDE Connect ; aucune suppression au retour de busctl/timeout ou arrêt du bridge. Implémentation isolée et tests synthétiques démarrent ; pas de vrai partage. - with pi 🥧
Author
Owner

Intégré sur main 42bdfdd, contenu distant de chaque fichier modifié vérifié :2ec03b3 +5ce5479. Gate parent combiné25/25 suites passent, dont25 staging,36 bridge, destinataire natif#14 et15 garde de collage#19. Revue indépendante : défaut d’ancêtres renommables corrigé, BLOCK retiré au head5ce5479 ; propriétaire/contexte sticky de chaque ancêtre et enfant vérifiés. Ancêtres 0777/0770 non sticky refusés, /tmp1777 sûr accepté ; aucun payload/shareUrl au refus.

Source ouverte une fois (NONBLOCK/CLOEXEC) puis fstat régulier et copie bornée du même descripteur, nom d’origine conservé. Liens symboliques de source vers fichier régulier toujours acceptés. Le destinataire#14 reste figé, recontrôle live inchangé. URI privée persistante fournie seulement après fermeture du fichier copié : remplacements/unlink ultérieurs du chemin source ne changent pas ses octets. Vrai faux-consommateur en processus séparé ouvre après sortie du bridge et lit le bon contenu malgré remplacement de source.

Choix approuvé : répertoire0700/fichier0600, propriétaires/liens/layout vérifiés, flock non bloquant sur préparation+dispatch ;512Mio/fichier,2Gio de quota comptabilisé (réservations +8Kio/entrée),64entrées. Refus à capacité, aucune éviction jeune. Budget3s coopératif, mémoire par chunks≤1Mio. Succès, incertitude et arrêt après spawn conservent la copie ; seuls échecs connus pré-dispatch/partiels la retirent. Pas de retry ni suppression au retour du voidshareUrl/timeout/sortie. Import/EOF/snapshot ne touchent pas HOME/cache.

Contrat et limites explicites : le code officiel KDE Connect26.08.2 ouvre en différé et n’expose aucun handle corrélé de prise en charge sortante.24h est un âge d’éligibilité au nettoyage, exécuté au prochain partage explicite, pas un événement de fin ni une suppression ponctuelle garantie. Un transfert exceptionnellement tardif peut échouer ; sans nouveau partage des copies anciennes peuvent persister. Contenu stocké sur disque privé, pas seulement en mémoire. Pas de snapshot atomique pendant écriture concurrente (changements usuels détectés) ni de délai I/O dur ; entrées incomplètes inconnues préservées et cache refusé plutôt que suppression arbitraire. Aucun fichier privé/téléphone réel utilisé.

La session active reste inchangée ; publication ≠ activation.

  • with pi 🥧
Intégré sur main [42bdfdd](https://git.2027a.net/mathieu/dotfiles/commit/42bdfdd5ceac3930b685ac5ffc291f34548c024f), contenu distant de chaque fichier modifié vérifié :2ec03b3 +5ce5479. **Gate parent combiné25/25 suites passent**, dont25 staging,36 bridge, destinataire natif#14 et15 garde de collage#19. Revue indépendante : défaut d’ancêtres renommables corrigé, BLOCK retiré au head5ce5479 ; propriétaire/contexte sticky de chaque ancêtre et enfant vérifiés. Ancêtres 0777/0770 non sticky refusés, `/tmp`1777 sûr accepté ; aucun payload/shareUrl au refus. Source ouverte une fois (`NONBLOCK/CLOEXEC`) puis `fstat` régulier et copie bornée du même descripteur, nom d’origine conservé. Liens symboliques de source vers fichier régulier toujours acceptés. Le destinataire#14 reste figé, recontrôle live inchangé. URI privée persistante fournie seulement après fermeture du fichier copié : remplacements/unlink ultérieurs du chemin source ne changent pas ses octets. Vrai faux-consommateur en processus séparé ouvre **après sortie du bridge** et lit le bon contenu malgré remplacement de source. Choix approuvé : répertoire0700/fichier0600, propriétaires/liens/layout vérifiés, flock non bloquant sur préparation+dispatch ;512Mio/fichier,2Gio de quota comptabilisé (réservations +8Kio/entrée),64entrées. Refus à capacité, aucune éviction jeune. Budget3s coopératif, mémoire par chunks≤1Mio. Succès, incertitude et arrêt après spawn conservent la copie ; seuls échecs connus pré-dispatch/partiels la retirent. Pas de retry ni suppression au retour du voidshareUrl/timeout/sortie. Import/EOF/snapshot ne touchent pas HOME/cache. **Contrat et limites explicites :** le code officiel KDE Connect26.08.2 ouvre en différé et n’expose aucun handle corrélé de prise en charge sortante.24h est un âge d’éligibilité au nettoyage, exécuté au prochain partage explicite, pas un événement de fin ni une suppression ponctuelle garantie. Un transfert exceptionnellement tardif peut échouer ; sans nouveau partage des copies anciennes peuvent persister. Contenu stocké sur disque privé, pas seulement en mémoire. Pas de snapshot atomique pendant écriture concurrente (changements usuels détectés) ni de délai I/O dur ; entrées incomplètes inconnues préservées et cache refusé plutôt que suppression arbitraire. Aucun fichier privé/téléphone réel utilisé. La session active reste inchangée ; publication ≠ activation. - with pi 🥧
mathieu 2026-10-24 17:47:37 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
mathieu/dotfiles#18
No description provided.