web-dev-qa-db-fra.com

Comment 'rm -rf /' peut-il supprimer tous les fichiers du système?

Je n'ai pas essayé cette commande sur Ubuntu (pour des raisons évidentes), donc je ne sais pas si Ubuntu autorisera son exécution. Mais c'est célèbre pour tout effacer. Juste par curiosité, que se passe-t-il lorsque le noyau et /bin sont supprimés? Comment rm conserve-t-il une pile d'exécution? Comment rm parvient-il à communiquer avec le système de fichiers et à supprimer complètement? Comment communique-t-il avec le matériel?

81
Muye

Peu importe que /bin/rm soit supprimé. Il n'est exécuté qu'une fois et à ce stade, tout est chargé en mémoire, de même que tout le reste nécessaire pour continuer à envoyer des suppressions au système de fichiers et au disque.


Barre latérale/Mise à jour: Per réponse de David Hoelzer (et mentionné dans les commentaires), l'inode du lien dur /bin/rm désignait resterait jusqu'au rm fini (parce que Linux est dans un état ouvert) mais ce fait est sans importance; l'état du disque n'a pas d'importance.

Le binaire est chargé en mémoire avant son exécution. Même si vous pouviez détruire manuellement les données du disque rm, cela n'affecterait ni n'arrêterait la suppression (si vous ne rendez pas le disque indisponible, sinon).

Aucune idée de ce qu’est un inode ou un lien physique? C’est la réponse à laquelle j’ai travaillé.


Quoi qu’il en soit, c’est aussi la raison pour laquelle vous pouvez supprimer le package pour le noyau actuel sans imploser l’ordinateur. Tant que vous installez une version différente, il pourra démarrer.

Encore une fois, cela fonctionne parce que rm n’est appelé qu’une fois. serait ​​échouera après la mort de /bin/rm 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 probablement aussi, car ils ont tous deux une limite d'arguments, ce qui signifie qu'ils ne supprimeraient qu'un certain nombre de fichiers avant d'être appelés à nouveau. À 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 pas garanti cependant. Si /bin/ était le dernier répertoire entré, ces méthodes pourraient ​​fonctionner.

78
Oli

Je n'ai pas essayé cette commande sur Ubuntu (pour des raisons évidentes), donc je ne sais pas si Ubuntu autorisera son exécution.

J'ai fait. rm -rf / --no-preserve-root était en cours d'exécution dans une session racine ouverte directement sur la machine, alors que j'étais également connecté via ssh à partir d'une autre machine, en utilisant également le compte root.

Qu'est-ce qui se passe 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é

enter image description here

É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:

Échec de lecture depuis le socket: réinitialisation de la connexion par un homologue

Sur la machine, il reste quatre répertoires:

  • /dev . C'est là que les fichiers de l'appareil sont stockés.
  • /proc - système de fichiers en mémoire créé par le noyau.
  • /run , emplacement de système de fichiers normalisé pour les démons.
  • /sys . Cela vous permet d'obtenir des informations sur le système et ses composants.

Cela signifie qu'il ne reste plus grand chose et qu'il n'y a pas grand-chose à faire là-bas. Vous ne pouvez pas ls (bien qu'en utilisant Tab, les noms des répertoires et des fichiers sont toujours affichés). Vous pouvez cd dans différents répertoires, ainsi que echo, mais des commandes telles que cat ne sont plus disponibles.

Il n'y a pas non plus de Sudo.

shutdown -h now et reboot ont également disparu, de sorte que votre seule option semble éteindre la machine manuellement. La déconnexion (exit) ne fonctionne pas, même si un texte "déconnexion" de Nice est affiché.

Une fois que vous essayez de redémarrer la machine, une erreur Nice GRUB _ 15 s'affiche, puis rien ne se produit. Vous pouvez alors commencer à penser que votre rm a pu nuire à votre système.

enter image description here

Tu peux le faire aussi

Non, attendez, ne le faites pas sur votre machine!

Au lieu de cela, vous pouvez exécuter une machine virtuelle . Les machines virtuelles ont l'avantage de rendre l'expérimentation vraiment facile. Puisque vous utilisez Ubuntu, vous pouvez être intéressé par vmbuilder . Ceci est un outil qui vous permet de déployer des machines virtuelles en quelques minutes (la documentation officielle affirme que cela peut être fait "en une minute environ", mais le temps réel, même sur du matériel rapide, est plutôt de deux à trois minutes. .

Une fois le déploiement terminé, vous disposez d'un environnement avec lequel vous pouvez jouer. Si vous finissez par le détruire, cela n'a pas d'importance: vous déployez à nouveau la machine et deux minutes plus tard, vous pouvez continuer.

Si vous utilisez un logiciel tel que VMWare, vous pouvez également être intéressé par les instantanés (notez que le lecteur VMWare gratuit ne possède pas cette fonctionnalité; vous devez acheter VMware Workstation). Notez que Hyper-V est gratuit et prend en charge les instantanés (mais vous devez exécuter Windows).

L'avantage des instantanés est que vous pouvez en prendre un en quelques millisecondes. Revenir à un instantané prend plus de temps, mais prend souvent quelques secondes. Cela rend l'expérimentation encore plus facile et 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. Vous avez une application suspecte? Testez-le sur une machine virtuelle. S'il s'agit d'un virus, cela ne fera aucun mal. Vous souhaitez tester une opération sur une base de données, étant donné que cela pourrait affecter l'environnement? Testez-le sur une VM.

Et si vous faisiez cela sur une vraie machine non testée?

Les mauvaises choses arrivent. Notez que rm vous protège de vous-même: rm -rf / ne fonctionnera pas: vous devez utiliser --no-preserve-root. Pourtant, que se passe-t-il si vous avez réellement réussi, par erreur, à tout supprimer?

rm dissocie uniquement les fichiers , mais les données sont toujours présentes sur votre disque dur. Cela permet de le récupérer ultérieurement (c'est pourquoi vous ne devriez pas simplement jeter vos disques durs contenant des données sensibles lorsqu'ils ne fonctionnent plus).

Cela signifie qu'il vous suffit de disposer d'un ordinateur de rechange avec un boîtier de disque dur pour pouvoir récupérer presque tous les fichiers . L'important est d'éviter d'écrire quoi que ce soit sur le disque dur à récupérer: les données que vous écrivez écraseront les fichiers non liés.

Comme noté dans l'article du commentaire de 200_success , si vous agissez intelligemment, vous pouvez récupérer la machine même sans PC de secours. Si vous vous souciez uniquement des données, cela ne me dérangerait pas: il est beaucoup plus facile de les récupérer avec un ordinateur de rechange.

57
Arseni Mourzenko

La raison en est que la couche de dénomination de fichier (ce que vous voyez avec lsname__) est vraiment juste pour votre commodité. Le pilote de système de fichiers et le noyau ne s’intéressent qu’à l’inode. Lorsqu'un fichier est référencé par son nom, il est immédiatement traduit dans l'inode qui contient toutes les métadonnées, y compris les autorisations, les blocs de données sur le disque, l'ID du propriétaire, l'ID du groupe et le nombre de liens.

Le nombre de liens est ce qui compte vraiment ici. Lorsque vous supprimez un fichier sur un système UNIX, l'appel système réel est un unlinkname__. Ce qui se passe sous le capot est que le nombre de liens (le nombre de noms de fichiers dans la couche de nommage de 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 rmname__, il édite également le fichier de répertoire (oui, il ne s'agit que d'un fichier contenant le nom du fichier et l'inode, ainsi que quelques autres bits qui ne sont pas importants pour cette réponse). Cependant, c'est la dissociation qui libère les ressources du disque.

Cela conduit à d'autres effets intéressants. Premièrement, il est possible d’avoir un fichier ouvert dont le nombre de liens est égal à zéro. Cela se produit lorsque rm -rf / supprime l'entrée pour /bin/rm. Le fichier est ouvert (il y a un descripteur de fichier) mais l'inode est marqué comme supprimé (nombre de liens = 0). Les ressources de disque ne seront pas libérées et réutilisées jusqu'à la fermeture du descripteur de fichier.

Un autre effet intéressant est ce qui se produit lorsque vous avez un inode avec un nombre de liens supérieur à zéro mais rien dans la couche de dénomination de fichier qui pointe vers lui. En un sens, c’est un fichier très bien caché :). Pour y accéder, vous devez utiliser un niveau bas pour le référencer par numéro d'inode plutôt que par nom (car il n'y en a pas) ou éditer une entrée de répertoire pour pointer l'inode à l'aide d'un éditeur hexadécimal.

Un troisième effet intéressant est ce qui arrive si vous réduisez le nombre de liens à zéro mais que vous pointez quand même une entrée de répertoire vers l'inode. Je vous laisse le soin d'expérimenter si vous le souhaitez. Clairement, cependant, ces deux dernières conduisent à un état de cohérence du système de fichiers.

25
David Hoelzer

Les réponses précédentes sont bonnes, mais je tiens à clarifier un détail:

rmn'est pas qu'une commande. C'est un programme qui se trouve dans PATHname__.

Par conséquent, ce qui se passe lorsque vous exécutez est le suivant:

  • vous appelez (en tant que root) rm -rf /
  • l'instance du programme rmest chargée en mémoire avec les arguments -rf et /
  • sur la base de ces arguments, le programme rmcommence ses opérations (passe en revue tout ce qui est monté dans/partition et supprime récursivement ses références [désolé pour la technicité;)])
  • une fois qu'il est terminé, l'instance du programme rmest déchargée
  • à ce stade, les seuls éléments en mémoire sont les programmes chargés auparavant (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'a été trouvé dans les emplacements PATH (et les emplacements PATH n'existent plus). Cependant, tout ce qui est chargé une fois encore fonctionnera

Juste pour comprendre comment cela fonctionne, essayez d'installer LAMP sur Ubuntu (dans Virtualbox), sur un script et sur le cache opcode PHP, puis appelez cette commande diabolique. Étonnamment (si vous êtes assez chanceux et que votre cache opcode ne remarquera 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 diabolique même exécutée en tant que root ne supprime pas everythingname__, elle ne peut pas supprimer certains processus privilégiés du noyau de /proc ni des éléments de périphériques de /dev qui apparaissent sur votre système sous forme de fichiers. En fait, root n’est pas aussi puissant que nous le pensons, le noyau en revanche l’est.

PPS: En même temps, vous aurez également des fichiers qui étaient lockedpar un autre processus au moment de la tentative de suppression.

18
Alexey Kamenskiy

Une fois que tout est effacé des disques durs, le noyau fonctionne toujours, mais il est en quelque sorte bloqué car il ne reste aucun périphérique, programme, commande, etc.

Le système d'exploitation ne fonctionnera plus.

Et c'est vrai ce que dit Oli, la commande est chargée/exécutée en mémoire et rien ne l'arrêtera à moins de tuer ce processus (bien sûr, si la commande kill est toujours présente ^^).

1
s1mmel

Sachez que si le système utilise selinux et que selinux est en mode d'exécution, les stratégies de selinux sont correctement configurées. alors rien ne va se passer.

Selinux est un contrôle d'accès obligatoire, ce qui signifie, entre autres choses, que l'utilisateur root n'a vraiment pas plus de pouvoir pour détruire le système que tout autre utilisateur du système.

Selinux est appliqué dans le noyau; vous devez compromettre le noyau pour le contourner.

Sur un système bien conçu avec de bonnes politiques Selinux, root ne pourrait pas faire grand chose sur le système.

Les versions ultérieures de Android appliquent Selinux uniquement pour cette raison.

0
Mark Allyn