Je n'ai pas essayé cette commande sur Ubuntu (pour des raisons évidentes) donc je ne suis pas sûr si Ubuntu permettra son exécution. Mais elle est célèbre pour supprimer tout. Juste par curiosité, que se passe-t-il lorsque le noyau et /bin
sont supprimés? Comment rm
maintient-il une pile d'exécution? Comment rm
parvient-il à communiquer avec le système de fichiers et à effectuer la suppression? Comment communique-t-il avec le matériel?
Réponses
Trop de publicités?Peu importe que /bin/rm
soit supprimé. Il ne s'exécute qu'une seule fois et à ce moment-là, tout est chargé en mémoire, tout ce qui est nécessaire pour continuer à envoyer des suppressions vers le système de fichiers et le disque.
Sidebar/Mise à jour : Selon la réponse de David Hoelzer (et mentionné dans les commentaires), l'inode auquel le lien physique /bin/rm
pointait resterait en place jusqu'à ce que rm
ait fini (parce que Linux le maintient dans un état ouvert) mais ce fait est sans importance ; l'état du disque n'a aucune importance.
Le binaire est chargé en mémoire avant de s'exécuter. Même si vous pouviez détruire manuellement les données disque de rm
, cela n'affecterait pas ou n'empêcherait pas la suppression de se terminer (en supposant que vous ne rendiez pas le disque indisponible).
Quoi qu'il en soit, c'est pourquoi vous pouvez supprimer le paquet pour le noyau actuel sans que l'ordinateur n'implose. Tant que vous installez une version différente, il pourra démarrer.
Encore une fois, cela fonctionne car rm
est appelé une seule fois. Ce qui suit échouerait après que /bin/rm
serait terminé car il l'appelle une fois pour chaque nom de fichier :
find / -exec rm {} \;
Cela dit, find / -exec rm -rf {} +
et find / -print0 | xargs -0 rm -rf
échoueraient également probablement car ils ont tous les deux des limites d'arguments, ce qui signifie qu'ils ne supprimeraient qu'un certain nombre de fichiers avant d'être rappelés. À un moment donné du voyage, /bin/rm
pourrait expirer (et être libéré) avant que le reste des fichiers ne soit supprimé. Ce n'est cependant pas garanti. Si /bin/
était le dernier répertoire entré, ces méthodes pourraient fonctionner.
Je n'ai pas essayé cette commande sur Ubuntu (pour des raisons évidentes) donc je ne suis pas sûr si Ubuntu permettra son exécution.
Je l'ai fait. rm -rf / --no-preserve-root
était en cours d'exécution dans une session root ouverte directement sur la machine, pendant que j'étais également connecté via ssh
depuis une autre machine, en utilisant également le compte root.
La conséquence est que vous commencez à recevoir beaucoup de messages comme :
rm: impossible de supprimer '/...': Opération non autorisée
ou :
rm: impossible de supprimer '/...': Périphérique ou ressource occupé
Étonnamment, la connexion ssh
est restée ouverte jusqu'à la fin de l'opération. Ce n'est que lorsque j'ai fermé la connexion et essayé de la rouvrir qu'une erreur est apparue :
La lecture depuis la socket a échoué : Connexion réinitialisée par l'hôte distant
Sur la machine, quatre répertoires restent :
/dev
. C'est là que les fichiers des périphériques sont stockés./proc
—un système de fichiers en mémoire créé par le noyau./run
, un emplacement standardisé du système de fichiers pour les démons./sys
. Cela permet d'obtenir des informations sur le système et ses composants.
Cela signifie qu'il ne reste pas grand-chose, et pas grand-chose à faire là-bas. Vous ne pouvez pas faire de ls
(bien que lorsque vous utilisez Tab, les noms des répertoires et des fichiers soient toujours affichés). Vous pouvez cd
dans différents répertoires, et aussi echo
des choses, mais des commandes telles que cat
ne sont plus disponibles.
Il n'y a pas de sudo
non plus.
shutdown -h now
et reboot
ont également disparu, donc votre seule option semble être d'éteindre manuellement la machine. La déconnexion (exit
) ne fonctionne pas, même si elle affiche un joli texte de "déconnexion".
Une fois que vous essayez de redémarrer la machine, vous obtenez une belle erreur GRUB 15, puis, rien ne se passe, à ce moment-là vous commencerez à penser que votre commande rm
a peut-être causé un problème à votre système.
Vous pouvez le faire aussi
Non, attendez, ne le faites pas sur votre machine !
Ce que vous pouvez faire à la place est d'exécuter une machine virtuelle. Les machines virtuelles ont l'avantage de rendre l'expérimentation vraiment simple. Comme vous utilisez Ubuntu, vous pourriez être intéressé par vmbuilder. C'est un outil qui vous permet de déployer des machines virtuelles en quelques minutes (la documentation officielle prétend que cela peut être fait "en environ une minute", mais le temps réel, même sur du matériel rapide, est plutôt de l'ordre de deux à trois minutes.
Une fois le déploiement terminé, vous disposez d'un environnement sur lequel vous pouvez jouer. Si vous le détruisez, ce n'est pas grave : déployez à nouveau la machine, et deux minutes plus tard, vous pouvez continuer.
Si vous utilisez des logiciels tels que VMWare, vous pourriez également être intéressé par des snapshots (notez que le VMWare Player gratuit n'a pas cette fonctionnalité ; vous devez acheter VMware Workstation). Notez que Hyper-V est gratuit et prend en charge les snapshots (mais vous devez exécuter Windows).
L'avantage des snapshots est que vous pouvez en prendre un en quelques millisecondes. Revenir à un snapshot prend plus de temps, mais se fait souvent en quelques secondes. Cela rend l'expérimentation encore plus facile et plus rapide.
Cette expérimentation ne se limite pas au système d'exploitation lui-même. Vous pouvez faire toutes sortes de choses impliquant des logiciels. Avez-vous une application suspecte ? Testez-la dans une machine virtuelle : si c'est un virus, il ne causera aucun problème. Vous voulez tester une opération sur une base de données, sachant qu'elle pourrait affecter l'environnement ? Testez-la dans une machine virtuelle.
Et si vous faisiez cela sur une vraie machine, non de test ?
Des choses désagréables se produisent. Notez que rm
vous protège de vous-même : rm -rf /
ne fonctionnera pas : vous devez utiliser --no-preserve-root
. Mais imaginez que, par erreur, vous parveniez à tout supprimer ?
rm
se contente de supprimer les liens vers les fichiers, mais les données sont toujours présentes sur votre disque dur. Il est donc possible de les récupérer ultérieurement (c'est pourquoi vous ne devriez pas jeter simplement vos disques durs contenant des données sensibles lorsqu'ils ne fonctionnent plus).
Cela signifie que vous devrez simplement disposer d'un PC de secours avec un boîtier de disque dur pour récupérer pratiquement tous les fichiers. L'important est d'éviter d'écrire quelque chose sur le disque dur à récupérer : les données que vous écrivez écraseront les fichiers non liés.
Comme l'a noté l'article dans le commentaire de 200_success, si vous agissez intelligemment, vous pouvez récupérer la machine même sans PC de secours. Si vous vous préoccupez seulement des données, je ne m'embêterais pas à les récupérer avec un PC de réserve, c'est bien plus facile.
La raison en est que la couche de nommage des fichiers (ce que vous voyez avec ls
) est vraiment juste pour votre confort. Le pilote du système de fichiers et le noyau se soucient uniquement de l'inode. Lorsqu'un fichier est référencé par son nom, il est immédiatement traduit en l'inode qui contient toutes les métadonnées, y compris les autorisations, les blocs de données sur le disque, l'identifiant du propriétaire, l'identifiant du groupe et le nombre de liens.
Le nombre de liens est ce qui importe vraiment ici. Lorsque vous supprimez un fichier sur un système UNIX, l'appel système réel est un unlink
. Ce qui se passe sous le capot, c'est que le nombre de liens (le nombre de noms de fichiers dans la couche de nommage des fichiers) pointant vers cet inode est décrémenté. Le système de fichiers sait qu'un fichier est supprimé lorsque le nombre de liens atteint zéro.
Lorsqu'un fichier est supprimé par rm
, il modifiera également le fichier répertoire (oui, c'est juste un fichier qui contient le nom du fichier et l'inode en plus de quelques autres éléments qui ne sont pas importants pour cette réponse). Cependant, c'est le désassemblage qui libère réellement les ressources du disque.
Cela conduit à quelques autres effets intéressants. Tout d'abord, il est possible d'avoir un fichier ouvert dont le nombre de liens est de zéro. Cela se produit lorsque rm -rf /
supprime l'entrée pour /bin/rm
. Le fichier est ouvert (il y a une poignée de fichiers pour y accéder), mais l'inode est marqué comme supprimé (nombre de liens = 0). Les ressources du disque ne seront pas libérées et réutilisées tant que la poignée de fichier ne sera pas fermée.
Un autre effet intéressant est ce qui se passe lorsque vous avez un inode avec un nombre de liens supérieur à zéro mais rien dans la couche de nommage des fichiers qui y pointe. C'est, en quelque sorte, un fichier très bien caché :). Pour y accéder, vous devriez utiliser quelque chose de bas niveau pour le référencer par son numéro d'inode plutôt que par son nom (car il n'y en a pas) ou éditer une entrée de répertoire pour pointer vers l'inode en utilisant un éditeur hexadécimal.
Un troisième effet intéressant est ce qui se passe si vous réduisez le nombre de liens à zéro mais pointez tout de même une entrée de répertoire vers l'inode. Je vous laisse expérimenter avec cela si vous le souhaitez. De toute évidence, ces deux derniers cas entraînent tous deux un état non cohérent du système de fichiers.
Les réponses précédentes sont bonnes, mais je veux clarifier un détail:
rm
n'est pas juste une commande. C'est un programme qui se trouve dans PATH
.
Par conséquent, voici ce qui se passe lorsque vous l'exécutez:
- vous appelez (en tant que root)
rm -rf /
- une instance du programme
rm
est chargée en mémoire avec les arguments-rf
et/
- basé sur ces arguments, le programme
rm
commence ses opérations (passant à travers tout dans la partition montée / et supprimant récursivement les références à cela [désolé pour la technicité ;)]) - une fois terminé, l'instance du programme
rm
est déchargée - à ce moment-là, les seules choses en mémoire sont les programmes qui ont été chargés précédemment (par exemple bash si vous avez un terminal ouvert dans Ubuntu, environnement de bureau, noyau, pilotes, etc.)
- si vous essayez d'appeler une autre commande (ce qui, dans le cas de Linux, en fait un programme autonome), elle échouera car aucun programme de ce type n'est trouvé dans les emplacements PATH (et les emplacements PATH n'existent plus). Cependant, tout ce qui a été chargé continuera toujours à fonctionner
Juste pour comprendre comment cela fonctionne, essayez d'installer LAMP sur Ubuntu (dans Virtualbox), un script et un cache d'opcode PHP, puis appelez cette commande malveillante. Étonnamment (si vous avez de la chance et que votre cache d'opcode ne remarque pas la suppression du fichier php), vous pouvez toujours accéder aux scripts php de l'extérieur via le serveur web apache!
PS: cette commande malveillante même exécutée en tant que root ne supprimera pas tout
, elle ne peut pas supprimer certains processus privilégiés du noyau de /proc
et ne peut pas supprimer certaines choses des périphériques /dev
qui apparaissent sur votre système sous forme de fichiers. En fait, root n'est pas aussi tout-puissant que nous pensons, le noyau en revanche l'est.
PPS: En y réfléchissant, vous aurez également toujours des fichiers qui ont été verrouillés
par un autre processus au moment de la tentative de suppression.
Une fois que tout est effacé des disques durs, le noyau continue à fonctionner mais reste bloqué car il n'y a plus de dispositifs, de programmes, de commandes, etc.
Le système d'exploitation ne fonctionnera plus.
Et ce que dit Oli est vrai, la commande est chargée/exécutée en mémoire et rien ne l'arrêtera à moins que vous ne tuiez ce processus (bien sûr, si la commande kill est toujours présente ^^).
- Réponses précédentes
- Plus de réponses