web-dev-qa-db-fra.com

Crash lors du démarrage sur un ordinateur d'entreprise récent

Après quelques mises à jour récentes, mon ordinateur ne démarre plus! Voici ce que j'ai pu déterminer:

  • Il s'agit d'un ordinateur très récent qui m'a été fourni par l'informatique d'entreprise. Il dispose d'un processeur Intel récent (génération Skylake).
  • L'ordinateur exécute Ubuntu 16.04.
  • L'ordinateur a démarré correctement pour la dernière fois en mars. Le problème est probablement dû à une mise à jour logicielle ou à un bug matériel.
  • J'ai un autre ordinateur exécutant 16.04 avec à peu près le même logiciel installé (j'ai utilisé apt-clone), et ça marche très bien. Il a un matériel différent (également AMD64, mais un processeur différent, un GPU différent, etc.).
  • Le noyau démarre, l'initrd fonctionne correctement. Lorsque je démarre avec un écran de démarrage en mode graphique, on me demande le mot de passe pour mon volume dm-crypt, et la dernière chose que je vois, c'est qu'il est monté avec succès.
  • Le blocage se produit avant que je reçoive une invite de connexion. Lorsque l'ordinateur se bloque, c'est un blocage. Même Alt+SysRq ne répond pas. Le CPU est évidemment fixé à 100% puisque les ventilateurs se mettent en marche à plein régime.
  • J'ai toujours le noyau que j'utilisais avant de redémarrer. Lorsque je sélectionne ce noyau dans le menu Grub, j'obtiens le même verrouillage. Il semble donc que ce soit un bogue de noyau préexistant qui soit déclenché par autre chose - mais quoi?
  • Si je désactive l'écran de démarrage (supprimer splash de la ligne de commande linux dans Grub), je vois un certain nombre de services démarrer, puis il se bloque.
  • Je peux obtenir un shell racine en ajoutant init=/bin/sh à la ligne de commande linux dans Grub. Je peux même aller plus loin en ajoutant

    systemd.unit=basic.target systemd.Shell
    

    Cela démarre un certain nombre de services et exécute un shell racine sur tty9.

  • Si je lance systemctl start multi-user.target à partir de ce shell racine, l'ordinateur se bloque. On peut donc supposer que le problème est déclenché par l'un de ces services.
  • L'Iran systemctl list-dependencies multi-user.target pour voir quels services démarrer. J'ai démarré manuellement les dépendances répertoriées une par une, et tout a très bien commencé.

Cela ressemble donc à un bug matériel (car il se produit sur un ordinateur mais pas sur l'autre) qui est déclenché par certains logiciels. Mais quel logiciel? Étant donné que l'ordinateur se bloque si fort, je ne peux pas obtenir de journaux. Je ne peux même pas obtenir de sortie de console utile.


Techniques de débogage utiles:

  • Alt+SysRq: clé magique SysRq , qui vous permet de faire des choses comme un redémarrage d'urgence. Il accède au noyau à un niveau très bas, il fonctionne donc dans tous les cas, sauf les pires. Dans mon cas, Alt+SysRq ne répond pas, ce qui montre la profondeur de l'accident.
  • Pour modifier les paramètres de démarrage, maintenez enfoncée Shift quelques secondes après la mise sous tension. Vous devez appuyer dessus une fois que le BIOS a initialisé le clavier, mais avant le démarrage du système d'exploitation. Cela fait apparaître le menu Grub .
  • Dans le menu Grub, appuyez sur e pour modifier la ligne de commande d'une entrée de menu. Pour modifier les paramètres de démarrage Linux, accédez à la ligne commençant par linux. Sur un Ubuntu moderne, vous trouverez d'anciens noyaux sous "Options avancées pour Ubuntu". Une fois que vous avez apporté les modifications souhaitées à la ligne de commande, appuyez sur Ctrl+x pour démarrer. Toutes les modifications que vous apportez ici concernent uniquement ce démarrage, elles ne sont pas enregistrées sur le disque.
  • Quelques options utiles sur la ligne de commande linux:
    • quiet nosplash masque presque tous les messages de démarrage. Supprimez-les pour obtenir des messages sur la console lors du démarrage, ce qui est nécessaire pour avoir une chance de diagnostiquer les problèmes.
    • recovery vous donne un shell racine avec presque aucun service. Vous devrez connaître le mot de passe root. L'entrée de menu "mode de récupération" l'utilise.
    • init=/bin/sh vous donne un shell racine sans aucun service. Pour reprendre le démarrage normal, exécutez exec init. Vous pouvez passer des options systemd à ce stade, par exemple exec init --unit=basic.target pour démarrer init et quelques services (notez que cela ne démarre en aucun cas pour vous connecter, il vaut donc mieux qu'un Shell s'exécute sur une autre console). Notez que le système de fichiers racine est monté en lecture seule; courir mount -o remount,rw / pour pouvoir y écrire.
    • systemd.unit=basic.target démarre un ensemble de services très basique. Notez que cela n'inclut aucun moyen de vous connecter! Vous pouvez en faire la valeur par défaut en exécutant systemctl set-default basic.target à une invite racine. Pour restaurer la cible par défaut d'origine, exécutez systemctl set-default graphical.target (ou systemctl set-default multi-user.target pour un serveur sans interface graphique).
    • systemd.debug-Shell démarre un shell racine sur tty9. Vous pouvez l'activer pour chaque démarrage en exécutant systemctl enable debug-Shell à une invite racine. N'oubliez pas de désactiver cette option après avoir résolu le problème avec systemctl disable debug-Shell. presse Alt+F9 pour passer à tty9.
    • Voir aussi Astuces Fedora systemd , Astuces pour le problème de démarrage d'Arch Linux .

Le problème

Il s'avère que mon problème est un problème connu entre le dernier microcode Intel sur (certains?) CPU Skylake et les noyaux Linux récents, qui est principalement déclenché par sssd . Voir buntu bug # 1759920 "intel-microcode 3.20180312.0 provoque un blocage à l'écran de connexion (w/linux-image-4.13.0-37-generic)" , ainsi qu'un certain nombre d'autres bogues qui se transforment sur le même problème, comme buntu bug # 1746806 "sssd semble planter les instances AWS c5 et m5, cause 100% CPU" et buntu bug # 1746418 "Le système se bloque lorsque démarrer Xorg après avoir installé linux-image-4.13.0-32-generic ” . Vous êtes susceptible de rencontrer ce bogue si:

  • Vous avez un processeur Intel très récent. Pour autant que je sache, ce bug ne survient que sur les processeurs Skylake .
  • Vous avez le paquet intel-microcode installé. Revenir à un noyau testé antérieur n'a pas fonctionné pour moi car je n'exécutais ce noyau qu'avec un microcode antérieur.
  • Votre ordinateur est connecté à un réseau d'entreprise (généralement LDAP ou Active Directory) pour l'authentification des utilisateurs. Bien qu'il existe d'autres façons de déclencher le bogue, l'exécution de sssd semble être le coupable le plus courant. Il y a également des rapports de crash Xorg .

Le bogue est dû aux atténuations du problème de sécurité Spectre qui a été publié en janvier 2018. Il y a une incompatibilité entre du code du noyau et certains microcode du processeur qui provoque un blocage dans certaines circonstances.

Comment réparer

  1. Si vous ne pouvez pas démarrer normalement, vous devrez modifier la ligne de commande du noyau à l'invite Grub. Voir la question pour des explications et des façons possibles d'obtenir un shell racine.
  2. Une solution de contournement pour ce bogue spécifique consiste à ajouter le paramètre noibpb à la ligne de commande du noyau ( 1746418/14 =, 1759920/56 ). Cela devrait vous permettre de démarrer normalement et d'effectuer certaines réparations.
    Cela désactive l'atténuation de la vulnérabilité à l'origine du problème, ce qui signifie que votre ordinateur est désormais vulnérable à certaines attaques. Ce sont des attaques locales, c'est-à-dire que l'attaquant doit exécuter du code sur votre machine, mais ces attaques peuvent potentiellement être exécutées, par exemple via JavaScript dans un navigateur Web.
    Si vous n'avez pas d'autre moyen, vous pouvez le rendre permanent en ajoutant noibpb à la ligne de commande du noyau jusqu'à ce que vous obteniez un noyau fixe.
  3. Dans Ubuntu, le correctif est attendu dans la semaine du 23 avril 2018 , dans ce qui sera vraisemblablement le noyau 4.4.0-117 et 4.13.0-39. En attendant, Tyler Hicks a publié des noyaux de test pour 4.4 et 4.1 .

Comment j'ai diagnostiqué le problème

J'ai essayé plusieurs choses (voir la question) et déterminé que le bug a été déclenché quelque part entre atteindre basic.target et atteignant multi-user.target. J'ai donc défini la cible systemd par défaut sur basic.target (systemctl set-default basic.target) et activé le debug-Shell un service (systemctl enable debug-Shell) pour obtenir un shell racine.

L'Iran systemctl list-dependencies multi-user.target et démarré manuellement les dépendances répertoriées une par une. Cela n'a pas déclenché le crash.

Tous les services ne sont pas gérés directement par systemd . Certains sont gérés comme pstart services et certains sont gérés comme scripts SysVinit . Le script Shell ci-dessous les exécute tous. Remarque: je ne l'ai testé qu'une seule fois et il s'est écrasé par conception.

#!/bin/sh
wants=$(systemctl show -p Wants multi-user.target | sed 's/^Wants=//' | tr ' ' '\n' | sort)
log=/var/tmp/multi-user-steps-$(date +%Y%m%d-%H%M%S)

log () {
  echo "$* ..." | tee -a "$log"
  sync
  "$@"
  ret=$?
  echo "$* -> $ret" | tee -a "$log"
  sync
  return $ret
}

# systemd services
for service in $wants; do
  log systemctl start $service
  sleep 2
done

# upstart services
for conf in /etc/init/*.conf; do
  service=${conf##*/}; service=${service%.conf}
  log service ${service} start
  sleep 2
done

# sysvinit services
for service in /etc/rc3.d/S*; do
  log ${service} start
  sleep 2
done

Mon ordinateur est tombé en panne après le démarrage de sssd. De là, une recherche sur le Web sur "sssd linux kernel hang" m'a conduit à https://bugs.launchpad.net/cloud-images/+bug/1746806 et au diagnostic et à la solution.