2 points par GN⁺ 4 시간 전 | 1 commentaires | Partager sur WhatsApp
  • GhostLock (CVE-2026-43499) est une vulnérabilité du noyau introduite dans Linux 2.6.39 et corrigée dans 7.1 ; elle permet à un attaquant local non privilégié de provoquer une UAF de pile avec de simples appels système de threading, exploitable pour obtenir les privilèges root et s’échapper d’un conteneur
  • Dans le chemin proxy Requeue-PI, remove_waiter() efface le champ pi_blocked_on de current au lieu de celui de la tâche réellement en attente, ce qui laisse, dans la tâche revenue en espace utilisateur, un pointeur vers une frame de pile libérée
  • En créant une boucle de dépendances PI avec trois futex et trois threads pour provoquer un rollback -EDEADLK, puis en construisant un faux rt_mutex_waiter dans le tampon de pile contrôlable de PR_SET_MM_MAP, on obtient une écriture de pointeur contrainte
  • L’exploit utilise prefetch pour trouver les adresses de base de KASLR et de physmap, place de fausses structures et une pile ROP dans la CPU entry area (CEA), puis écrase inet6_protos[IPPROTO_UDP] pour détourner le flux de contrôle via un paquet IPv6 UDP en loopback
  • Les chercheurs ont reçu 92 337 $ dans Google kernelCTF pour un exploit d’élévation de privilèges et d’évasion de conteneur stable à 97 % ; toutes les distributions Linux non corrigées doivent être mises à jour vers la dernière version LTS

Portée de l’impact et aperçu de la vulnérabilité

  • GhostLock est une vulnérabilité du noyau Linux découverte par VEGA, déclenchable par un utilisateur local non privilégié sans droits particuliers ni namespace utilisateur
  • Elle a été introduite par le remaniement de rtmutex dans 8161239a8bcc, et la portée affectée va de v2.6.39-rc1 à v7.1-rc1
  • Elle a été corrigée en avril 2026 dans 3bfdc63936dd, et le seul paramètre de noyau nécessaire est CONFIG_FUTEX_PI=y
  • Un attaquant peut élever ses privilèges en suivant le processus suivant
    • obtenir, uniquement avec des appels système de threading ordinaires, un pointeur noyau pendant vers de la mémoire de pile noyau
    • créer une primitive contrainte permettant d’écrire un pointeur ou 8 octets nuls à une adresse presque arbitraire
    • détourner une table de fonctions pour prendre le contrôle du flux d’exécution et obtenir les privilèges root
  • Toutes les distributions Linux non corrigées étant affectées, il faut passer à la dernière version LTS

Pourquoi remove_waiter() nettoie la mauvaise tâche

  • remove_waiter(), dans kernel/locking/rtmutex.c, a été écrit à l’origine pour le chemin où un thread bloqué nettoie lui-même son état d’attente
  • Dans le slow path normal, le current en cours d’exécution est la tâche propriétaire du waiter ; effacer current->pi_blocked_on est donc correct
  • Dans le chemin proxy Requeue-PI, rt_mutex_start_proxy_lock() met en file un rt_mutex_waiter au nom d’une autre tâche endormie, puis l’annule en cas d’erreur
    • current est alors le requeuer qui a appelé FUTEX_CMP_REQUEUE_PI
    • le véritable waiter est une tâche distincte endormie dans FUTEX_WAIT_REQUEUE_PI
  • Lorsque __rt_mutex_start_proxy_lock() renvoie -EDEADLK, remove_waiter() retire le waiter du verrou, mais met uniquement current->pi_blocked_on à NULL
  • Le pi_blocked_on du véritable waiter continue de pointer vers le rt_mutex_waiter situé sur sa propre pile noyau ; lorsque le waiter revient en espace utilisateur, cette frame de pile est considérée comme libérée
  • Ensuite, au moment où le parcours de la chaîne PI passe par cette tâche, il déréférence un objet de pile libéré
  • lockdep vérifie seulement quel pi_lock est détenu, sans vérifier à qui appartient ce lock, et ne détecte donc pas cette erreur

La boucle à trois futex qui provoque le rollback -EDEADLK

  • Pour atteindre le chemin d’erreur, on construit une boucle de dépendances PI avec trois futex et trois threads
    • f_pi_chain : futex PI que le waiter verrouille en premier
    • f_pi_target : futex PI que l’owner verrouille en premier et qui devient la cible du requeue
    • f_wait : futex ordinaire sur lequel le waiter attend avec FUTEX_WAIT_REQUEUE_PI
  • L’ordre de déclenchement est le suivant
    1. le waiter verrouille f_pi_chain, puis se bloque dans FUTEX_WAIT_REQUEUE_PI(f_wait -> f_pi_target), et le rt_mutex_waiter est placé sur sa pile noyau
    2. l’owner verrouille f_pi_target, puis se bloque sur f_pi_chain, détenu par le waiter
    3. le thread main appelle FUTEX_CMP_REQUEUE_PI(f_wait -> f_pi_target)
  • Lorsque le requeue proxy tente de relier le waiter à f_pi_target, la boucle waiter → f_pi_target → owner → f_pi_chain → waiter se referme
  • Le parcours de la chaîne PI renvoie -EDEADLK et exécute le mauvais rollback, réveillant le waiter avec un pi_blocked_on pendant
  • La condition importante est que le requeuer effectue le rollback pendant que le waiter détient encore l’objet de pile ; une fois la boucle formée, le processus se poursuit de lui-même
  • Une fois le waiter revenu en espace utilisateur, il n’y a plus de contrainte temporelle, et un parcours de chaîne peut être déclenché plus tard à tout moment avec sched_setattr()
  • La configuration utilise trois threads, mais la course UAF elle-même peut être déclenchée même avec un seul cœur CPU

Primitive initiale fournie par l’UAF de pile

  • Le pointeur pendant pointe vers le rt_mutex_waiter qui se trouvait dans l’ancienne frame FUTEX_WAIT_REQUEUE_PI
  • En replaçant des octets contrôlables à la même profondeur de pile dans la même tâche, on peut faire en sorte que le noyau les déréférence comme un faux rt_mutex_waiter
  • Selon la manière dont la fausse structure est placée, un seul accès permet d’obtenir deux primitives principales
    • écrire un pointeur à une adresse presque arbitraire, sous contraintes
    • écrire 8 octets nuls à une adresse presque arbitraire, sous contraintes
  • Plusieurs déréférencements de pointeurs et contrôles d’intégrité sont effectués avant l’écriture, mais si les conditions sont remplies, le noyau ne plante pas après l’écriture et revient normalement
  • Pour finaliser l’exploit, il faut à la fois réutiliser la frame de pile, passer les contrôles de structure du faux waiter et choisir une cible satisfaisant les contraintes d’écriture

Réutilisation d’un frame de pile libéré avec PR_SET_MM_MAP

  • Le waiter appelle prctl(PR_SET_MM, PR_SET_MM_MAP, ...) dès son retour de l’appel système futex
  • prctl_set_mm_map() copie l’auxv fourni par l’utilisateur dans un tampon de pile de taille fixe unsigned long user_auxv[AT_VECTOR_SIZE]
  • Comme ce tampon se trouve à une profondeur de pile similaire à celle du waiter libéré, un gros bloc de qwords contrôlables et alignés se superpose à l’ancien rt_mutex_waiter
  • La zone de chevauchement de l’auxv est configurée comme suit
    • tree : en fait un nœud rb qui, lors de la suppression, promeut le pointeur enfant choisi W0_BASE en racine de l’arbre
    • task : défini sur &init_task pour traverser sans risque les déréférencements de la recherche de chaîne
    • lock : fixé à &inet6_protos[IPPROTO_UDP] - 8 afin d’aligner la cible d’écriture
    • wake_state : défini à 0
  • L’auxv est placé dans un memfd et positionné de sorte que la copie franchisse une limite de page ; puis un thread frère crée une course avec fallocate(PUNCH_HOLE) sur la page arrière pendant l’exécution de prctl, afin d’allonger la durée de copy_from_user
  • Un thread consumer sur un autre CPU appelle sched_setattr() sur le waiter tant que le faux waiter reste sur la pile, ce qui déclenche la recherche de la chaîne PI
  • D’autres appels système utilisant de grandes variables locales contrôlables sur la pile, comme clone, setsockopt, pselect ou keyctl, peuvent remplir le même rôle
  • prctl a été choisi parce que son tampon est grand, aligné et ne nécessite pas de namespace ; d’autres candidats sont inclus dans le code PoC public

Créer une écriture de pointeur contrainte via la suppression dans un rb-tree

  • Même en contrôlant le faux waiter, on n’obtient pas immédiatement une écriture arbitraire complète ; la recherche de chaîne exécute le chemin suivant
    • trouve le faux waiter via task->pi_blocked_on
    • trouve le faux rt_mutex_base via fake waiter->lock
    • rt_mutex_dequeue(lock, waiter) effectue une suppression rb-tree dans lock->waiters
  • On exploite la propriété selon laquelle, lorsqu’on supprime un nœud racine n’ayant qu’un seul enfant, cet enfant est écrit dans le slot racine
  • Si lock est fixé à target - 8, les données voisines sont interprétées comme les champs suivants de rt_mutex_base
    • target - 8 : wait_lock, qui doit être lu comme non verrouillé
    • target : waiters.rb_root.rb_node à écraser
    • target + 8 : waiters.rb_leftmost
    • target + 16 : owner
  • L’unique écriture exécutée au final est *(uint64_t *)target = W0_BASE
  • L’adresse cible doit globalement satisfaire les conditions suivantes
    • les 32 bits de poids faible de target - 0x08 doivent valoir 0
    • la valeur 64 bits de target + 0x08 doit valoir 0
    • la valeur du pointeur owner à target + 0x10, hors flags de poids faible, doit valoir 0
  • Si le qword précédent ressemble à un spinlock verrouillé, le trylock échoue et l’exécution se termine sans rien écrire
  • Si les valeurs suivantes pointent vers un top waiter ou un owner non contrôlé, ou vers une valeur non mappée, un kernel panic peut survenir
  • Comme W0_BASE doit rester valide jusqu’à la fin des comparaisons, du requeueing, des mises à jour de priorité et du wakeup sans owner, on utilise l’alias direct-map du CEA

Fuite par prefetch et CPU entry area

  • Trouver les adresses de base KASLR et physmap

    • Le temps d’exécution de prefetch pour une adresse donnée varie selon que cette adresse est mappée ou non dans la table de pages courante
    • Un processus non privilégié peut estimer les emplacements mappés en mesurant les temps d’exécution dans la plage d’adresses du noyau ; le principe détaillé est décrit dans l’article sur prefetch
    • Comme l’entropie de l’adresse de base de l’image du noyau Linux par défaut est d’environ 9 bits, des mesures répétées permettent de récupérer l’adresse de base KASLR avec une fiabilité proche de 100 %
    • En théorie, les CPU disposant de prefetch et dépourvus d’un KPTI approprié sont affectés, mais en pratique la technique est surtout utilisée sur x86 avec KPTI désactivé
    • L’image kernelCTF a KPTI désactivé ; même avec KPTI activé, combiner prefetch avec EntryBleed permet de récupérer l’adresse de base de l’image noyau via le trampoline
  • Contournement de la randomisation des adresses CEA

    • La CPU entry area (CEA) est une structure propre à chaque CPU x86 qui conserve les piles d’entrée et de gestion d’exceptions ainsi que le contexte des registres
    • Lorsqu’un programme non privilégié déclenche une exception logicielle, son propre contexte de registres est écrit dans pt_regs sur la pile d’exception CEA, créant environ 120 octets de mémoire contiguë contrôlable
    • Avant Linux 6.2, l’adresse virtuelle du CEA était entièrement fixe, ce qui permettait de l’utiliser directement pour de fausses structures, absorber les effets de bord des déréférencements de pointeurs et construire une pile ROP
    • Après la publication par Project Zero de Bringing back the stack attack, l’adresse virtuelle du CEA est fortement randomisée depuis Linux 6.2
    • L’adresse virtuelle du CEA de chaque CPU est randomisée différemment, mais son adresse physique reste fixe ; connaître l’adresse de base du physmap permet donc de calculer l’alias direct-map
    • En combinant prefetch, la normalisation des limites candidates et la vérification des pages CEA attendues, on écarte les alias voisins et on obtient cea_direct = physmap_base + CPU1_CEA_BASE
    • Dans l’environnement de démarrage 3,5 Go de kernelCTF LTS 6.12.80, l’offset associé est 0x11c517000(+0x1f58)

Réutiliser le CEA comme faux waiter et comme objets ultérieurs

  • Avant la première écriture, un faux waiter et un lock auto-cohérents sont placés dans W0 du CEA
    • task est défini sur &init_task
    • prio reçoit une valeur valide
    • le wait_lock du lock est rendu visible comme non verrouillé
    • l’owner est configuré pour traverser sans risque les étapes de dequeue, requeueing, mise à jour de priorité et wakeup
  • Une fois l’écriture rb-tree terminée, W0 n’a plus besoin d’être un waiter ; le CEA peut alors être rempli de nouveau avec la structure requise par la cible écrasée
  • Le CEA est petit, environ 120 octets, mais il est efficace car il permet de placer des données à une adresse noyau fixe calculable
  • NPerm et kernelsnitch peuvent remplir le même rôle dans un espace plus large
  • L’exploit utilise une même zone CEA, séquentiellement ou simultanément, comme faux rt_mutex_waiter, faux lock, inet6_protocol, slots de JOP et de pivot de pile, puis pile ROP finale

Prise de contrôle du flux d’exécution via inet6_protos[IPPROTO_UDP]

  • Sur un Linux x86_64 courant, une fois l’adresse de base KASLR obtenue, on peut choisir un chemin court qui écrase une table de fonctions appropriée ou un objet qui la contient
  • La zone autour de inet6_protos[IPPROTO_UDP] dans la section de données inscriptible satisfait naturellement les contraintes nécessaires
    • inet6_protos[16] == NULL devient l’état non verrouillé du faux wait_lock
    • inet6_protos[17] == &udpv6_protocol est la véritable cible à écraser
    • inet6_protos[18] == NULL devient le faux rb_leftmost
    • inet6_protos[19] == NULL devient le faux owner
  • Une fois l’écriture terminée, inet6_protos[IPPROTO_UDP] pointe vers un faux inet6_protocol dans une page CEA
  • On projette à nouveau la CEA et on construit la structure comme suit
    • handler : défini sur le premier gadget de pivot
    • err_handler : non utilisé
    • flags : définis à INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL
  • En envoyant un paquet IPv6 UDP en loopback qui écrit des données après un connect vers ::1, le noyau appelle le faux handler, ce qui permet de contrôler le compteur de programme

Pivot court et élévation de privilèges DirtyMode

  • Sur la cible lts-6.12.80 de Google kernelCTF, aucun gadget de pivot de pile unique adapté n’a été trouvé ; une instruction load/call supplémentaire place donc l’adresse CEA dans rbp, puis le pivot se fait avec mov rsp, rbp; pop rbp; ret
  • ret2usr ou l’écrasement complet de /proc/%P/fd/x nécessite environ 10 qwords de gadgets, ce qui est trop volumineux pour l’espace CEA limité
  • L’étape finale utilise DirtyMode, qui modifie les bits de permissions en une seule écriture puis effectue le reste depuis l’espace utilisateur
  • La cible d’écriture est coredump_sysctls[1].mode dans les données du noyau, c’est-à-dire le mode d’accès du sysctl core_pattern
  • Comme il partage le même décalage KASLR que l’image du noyau, son adresse peut être calculée ; il suffit d’une valeur avec le bit d’écriture, le deuxième bit de poids faible, positionné
  • Une courte chaîne pop reg; mov [reg], reg; ret modifie la valeur du mode, puis msleep met en pause en toute sécurité le thread détourné
  • Une fois /proc/sys/kernel/core_pattern inscriptible par tous les utilisateurs, un processus non privilégié écrit |/proc/%P/fd/666 %P et fait crasher le helper, ce qui amène le noyau à exécuter le binaire de l’attaquant avec les privilèges root
  • En raison de contraintes d’alignement par lots, l’écriture initiale via rb-tree ne peut pas atteindre directement coredump_sysctls[1].mode ; la modification du mode est donc effectuée dans la courte étape ROP

Déroulé complet de l’exploit et résultat

  • L’attaque se déroule dans l’ordre suivant
    1. fuite du slide de l’image noyau et de l’adresse de base physmap avec prefetch
    2. utilisation de GhostLock pour laisser un rt_mutex_waiter pendant dans pi_blocked_on du waiter
    3. réutilisation de la même frame de pile noyau avec PR_SET_MM_MAP pour créer un faux waiter
    4. écriture d’un pointeur CEA dans inet6_protos[IPPROTO_UDP] via la suppression dans le rb-tree de rtmutex
    5. placement dans la CEA du faux inet6_protocol, des emplacements de pivot et de la pile ROP
    6. appel du handler écrasé au moyen d’un paquet IPv6 UDP en loopback
    7. modification du bit de mode de core_pattern avec DirtyMode et finalisation de l’élévation de privilèges depuis l’espace utilisateur
  • Dans l’environnement distant de kernelCTF, le chemin combinant CEA et DirtyMode obtient le flag en environ 5 secondes
  • L’exploit complet est publié dans le projet CyberMeowfia
  • Sur Android, la réutilisation des frames de pile et les méthodes de contournement d’ASLR et de CFI diffèrent ; elles feront l’objet d’un article de suivi séparé

Chemins alternatifs et mesures d’atténuation

  • Espace ROP plus grand

    • La mémoire basée sur NPerm peut servir de grande fausse pile après la prise de contrôle du flux d’exécution
    • Des chemins plus lourds sont aussi possibles, comme la fuite heap-KASLR de Lukas Maar, mais ils ajoutent des étapes et allongent le temps d’exécution
    • Dans kernelCTF, la chaîne la plus courte et la plus fiable est préférable ; la combinaison CEA et DirtyMode a donc été utilisée
  • Correctif du noyau

    • Le correctif final prend le pi_lock et efface pi_blocked_on en se basant sur waiter->task plutôt que sur current
    • remove_waiter() enregistre waiter_task = waiter->task, puis procède dans l’ordre suivant
      1. verrouille waiter_task->pi_lock
      2. retire le waiter de la file rtmutex
      3. définit waiter_task->pi_blocked_on = NULL
      4. transmet aussi waiter_task, au lieu de current, au rt_mutex_adjust_prio_chain() suivant
    • Le correctif séparé envoyé par les chercheurs avant la v1 faisait transmettre explicitement par l’appelant la tâche propriétaire
      • dans le chemin où la tâche se bloque elle-même, il transmet current
      • lors d’un rollback proxy, il transmet la task cible du proxy
      • il n’efface pi_blocked_on que si celui-ci pointe encore vers le waiter concerné, et le protège avec le pi_lock de la tâche
  • RANDOMIZE_KSTACK_OFFSET

    • L’exploit repose sur un chevauchement déterministe entre la frame du waiter libérée et la frame user_auxv suivante
    • Activer RANDOMIZE_KSTACK_OFFSET fait varier l’offset de pile, transformant cette étape en une devinette de 5 bits avec environ 1 chance sur 32
    • Sur les deux cibles générales soumises, ce réglage était désactivé par défaut ; sur la cible avec atténuations, il était activé, si bien que ce chemin d’exploitation n’a pas été utilisé
  • STATIC_USERMODE_HELPER

    • STATIC_USERMODE_HELPER bloque ce chemin DirtyMode précis
    • Toutefois, la même méthode peut être généralisée à d’autres réglages /proc/sys dont les permissions d’accès sont contrôlées par ctl_table::mode et dont la table se trouve dans des données noyau inscriptibles et prévisibles

Calendrier de divulgation

  • 18 avril 2026 : la vulnérabilité et un correctif préliminaire sont transmis à security@kernel.org
  • 20 avril 2026 : la vulnérabilité est corrigée par un autre patch
  • 4 mai 2026 : le correctif v1 est rétroporté
  • 30 juin 2026 : Google confirme la soumission à kernelCTF
  • 7 juillet 2026 : l’analyse technique est publiée
  • La vulnérabilité découverte par VEGA relève de la politique de divulgation standard 90+30 jours

1 commentaires

 
GN⁺ 4 시간 전
Commentaires sur Hacker News
  • J’ai testé sur 3 appareils utilisant Android 9, 13 et 16, avec différentes versions de Firefox antérieures à 150 : 2 sont partis en boucle de démarrage et ont dû passer en mode de récupération, et le 3e s’est éteint. La démo change le fond d’écran sur les appareils Pixel pris en charge, et la page de test est disponible sur IonStack
    Quand on consulte des blogs ou des sites arbitraires sur un appareil personnel, il est plus sûr d’installer en plus du navigateur principal un navigateur basé sur Chromium comme Chromite, de désactiver dans les flags JavaScript et le décodeur vidéo à accélération matérielle souvent visé, puis d’utiliser le mode lecture sur les sites cassés. Sinon, on peut aussi garder une tablette dédiée

    • Pour l’instant, les tests n’ont été faits que sur le Pixel 10, mais plusieurs PR visant à prendre en charge d’autres appareils sont en cours, à voir sur https://github.com/NebuSec/CyberMeowfia
    • En essayant de porter l’exploit noyau sur d’autres appareils, j’ai constaté qu’il était très sensible à la manière dont le compilateur dispose les stack frames à chaque build du noyau. Une fois trouvés le schéma de tamponnage et les offsets adaptés à un build donné, cela fonctionne de façon assez stable
    • J’ai pris le risque de l’exécuter sur un Samsung S26 Ultra, et je compte publier les résultats complets après vérification via adb
      En accédant à cette page de test, une sortie est apparue dans l’onglet Firefox, ce qui donnait l’impression que le code de preuve de concept s’était exécuté, mais ensuite le téléphone s’est figé et a refusé toute entrée. Seul le redémarrage fonctionnait. Je me demande comment l’événement de redémarrage peut encore être pris en compte dans une situation où le noyau semble gelé. L’écran est resté allumé en affichant une partie du résultat de l’exécution, puis l’économiseur d’écran s’est activé
    • Ce serait énorme si cela pouvait être utilisé pour rooter des appareils Android qui ne peuvent pas encore l’être ; je me demande si c’est possible
    • La faille Firefox semble être CVE-2026-10702, une confusion de types dans le compilateur JIT IonMonkey : https://www.sentinelone.com/vulnerability-database/cve-2026-10702/
  • Immense respect aux chercheurs en sécurité qui n’ont pas seulement trouvé l’exploit, mais qui, contrairement à copyfail, n’ont pas publié un script zero-day d’élévation locale de privilèges immédiatement exploitable par n’importe qui
    J’ai essayé pendant plusieurs heures d’obtenir une élévation locale de privilèges (LPE) sur Rocky Linux 9, heureusement sans succès. À moins d’avoir beaucoup de temps libre ou un très haut niveau, cela semble difficile à utiliser dans une attaque réelle sur une distribution d’entreprise

  • Je me demande s’il serait possible d’utiliser cette faille pour déverrouiller le bootloader même sur des téléphones où il ne peut généralement pas l’être. Si oui, ce pourrait être l’un des plus grands événements de l’écosystème Android

  • Le titre aurait dû inclure LPE, au sens d’élévation locale de privilèges, afin que la plupart des gens puissent se rassurer et retourner tranquillement à leur week-end

    • Il ne faut pas trop se rassurer. En général, un exploit local de privilèges désigne une attaque qui passe des privilèges d’un utilisateur ordinaire à ceux de root, et une appli avec des privilèges ordinaires peut déjà causer de gros dégâts, donc on ne s’en inquiète souvent pas trop
      Mais cette attaque-ci peut aussi être déclenchée depuis un processus fortement sandboxé, comme le processus navigateur isolé de Firefox. Il suffit à l’attaquant d’enchaîner une faille JavaScript pour exécuter du code local dans la sandbox isolée, puis cette faille-ci pour monter jusqu’au mode noyau : il faut donc mettre à jour à la fois Firefox et le noyau Linux
    • L’attaque du commentaire du dessus donne l’impression d’obtenir les privilèges root directement depuis JavaScript, mais en réalité elle enchaîne deux exploits distincts
    • Si une évasion de conteneur est possible, cela pourrait encore toucher beaucoup de monde, non ?
    • Puisqu’ils ont aussi découvert une confusion de types dans Firefox/IonMonkey, le simple fait de visiter un site arbitraire pourrait très vite mener à la compromission de l’appareil
    • J’ai l’impression qu’il doit exister aujourd’hui des centaines de zero-days mis de côté pour ce genre de situation. Entre SSH et Node.js, de nouveaux problèmes sortent toutes les quelques semaines ; à ce rythme, à moins de tout mettre derrière WireGuard, il faut pratiquement considérer que tout est vulnérable à distance
  • La phrase « Google a versé 92 337 dollars de récompense kernelCTF » a immédiatement attiré mon attention

    • Vu l’ampleur de l’impact, cela paraît peu. Je me demande si les entreprises ne paient vraiment très cher que pour les exploits à distance
  • Est-ce que cela signifie qu’une appli Android peut exécuter du code natif via le NDK pour obtenir les privilèges root, et que je me demande si SELinux aide à se défendre

    • Les téléphones non flagship reçoivent rarement des mises à jour, noyau compris, donc cela semble réellement possible avec une probabilité élevée
      On peut certes backporter des correctifs sur d’anciens noyaux, mais les notes de mise à jour des smartphones mentionnent rarement les CVE, si bien qu’un outil de vérification des vulnérabilités reste pratiquement le seul moyen de confirmer. Si une appli obtenue sur le Play Store ou ailleurs a été compromise, elle peut obtenir immédiatement les privilèges root ; les principes de confiance et d’audit au moment de l’installation restent donc importants
      À l’avenir, cette vérification pourrait être ajoutée à tous les niveaux de Google Play Integrity, empêchant l’installation de nombreuses applis sur les téléphones non corrigés. C’est encore plus grave dans un navigateur, où une évasion de sandbox contourne aussi l’isolation des applis ; cela rappelle JailbreakMe sur iOS
    • Si le noyau lui-même est compromis, SELinux ne peut pas défendre. Le sandboxing Android ou les technologies de conteneur comme Docker ne peuvent pas non plus bloquer cet exploit ; le seul moyen réaliste d’isolation est la virtualisation complète. Si vous utilisez KVM, cela suppose que le correctif de la CVE-2026-53359 publiée la semaine dernière a bien été déployé partout
      Sur tout Linux des 15 dernières années, n’importe quelle appli capable d’exécuter du code natif peut obtenir les privilèges root sur l’appareil tant qu’une mise à jour du noyau n’est pas arrivée
  • Il est sidérant de voir que GhostLock a été introduit dans Linux 2.6.39 et n’a été corrigé qu’avec Linux 7.1

  • J’ai l’impression d’avoir déjà lu ces commentaires hier, mais leur heure de publication est affichée comme étant inférieure à 10 heures ; je me demande si l’affichage du temps sur HN est erroné

    • C’est probablement dû au système de remise en avant (re-up) de HN. Quand ce billet a été republié, les horodatages des anciens commentaires ont été recalculés en temps relatif ; on peut voir des explications à ce sujet ici : https://hn.algolia.com/?dateRange=all&page=0&prefix=true&query=by%3Adang%20timestamps%20re-up&sort=byDate&type=comment
      En consultant chaque jour la liste « underwater », c’est-à-dire les billets ayant reçu beaucoup de votes mais qui, pour une raison ou une autre, n’ont pas atteint la page d’accueil, celui-ci était tout en haut, donc il a été remis en avant. Cela paraît étrange, mais on n’a pas encore trouvé d’alternative moins déroutante
    • Il arrive aussi que des articles similaires soient fusionnés en un seul, commentaires compris