Depuis quand le rm POSIX et GNU ne supprime-t-il pas /?

23

Depuis plusieurs années maintenant, l' rmutilitaire GNU ne supprimera pas à /moins qu'il ne soit appelé avec l' --no-preserve-rootoption. Cependant, le commandement rm -rf /a été déposé dans le subconscient collectif comme dangereux pendant très longtemps et les gens le citent encore souvent comme un commandement "effrayant".

Je me demandais quand cette règle qui rmne peut pas être supprimée /est apparue pour la première fois. J'ai vérifié les spécifications POSIX et je peux voir que même si POSIX: 2008 inclut cette fonction de sécurité, POSIX: 2001 ne le fait pas. Étant donné que les versions en ligne des spécifications POSIX sont mises à jour de temps en temps, avec chaque nouvelle sous-version, j'ai également vérifié la machine de retour et trouvé la page pertinente de POSIX: 2008 à partir de 2010 et j'ai pu confirmer que la règle qui rmne peut pas être supprimée /était déjà répertorié à l'époque.

Donc, mes questions sont:

  • Quand la règle qui rmne peut pas être supprimée a-t-elle été /ajoutée aux spécifications POSIX? Était-ce dans l'édition originale de 2008 de la version 4 de la spécification UNIX unique ou a-t-il été ajouté dans une révision?
  • Quand cette limitation a-t-elle été ajoutée à GNU rm? Je suis sûr que c'était avant qu'il ne soit ajouté à POSIX, mais quand est-ce arrivé?
terdon
la source
1
Connexes: Austin Group Interpretation # 019 (2003), qui décrit (mais n'a pas mis en œuvre) le changement.
Michael Homer
4
2003-11-09 git.savannah.gnu.org/gitweb/…
ilkkachu

Réponses:

28

Vous pouvez trouver la version HTML de toutes les éditions de POSIX 2008 en ligne:

Cela a été ajouté dans l'édition 2008.

Les rectificatifs techniques n'ajoutent généralement pas de nouvelles fonctionnalités.

Vous pouvez voir que la version précédente ( http://pubs.opengroup.org/onlinepubs/009695399/utilities/rm.html ) (POSIX 2004) n'avait pas ce texte.

Le nouveau texte a été accepté lors de la conférence du groupe Austin 2003-05-09 pour inclusion dans une révision ultérieure de la norme.

Elle a été demandée par John Beck de Sun Microsystems en mars de la même année (le lien nécessite l'enregistrement d'un groupe ouvert, voir également Enhancement Request Number 5 ici ).

John Beck a écrit, le 11 mars 2003:

@ page 820 line 31681-31683 section rm comment {JTB-1}

Problem:

Defect code :  3. Clarification required

An occasional user mistake, with devastating consequences, is to
write a shell script with a line such as:
      rm -rf $VARIABLE1/$VARIABLE2
or
      rm -rf /$VARIABLE1
without verifying that either variable is set, which can lead to
      rm -rf /
being the resulting command.  Since there is no plausible
circumstance under which this is the desired behavior, it seems
reasonable to disallow this.  Such a safeguard would, however,
violate the current specification.

Action:

Either extend the exceptions for . and .. on the noted lines
to list / as well, or specify that the behavior of rm if an
operand resolves to / is undefined.

GNU rmajouté --preserve-rootet --no-preserve-rootoptions dans cette validation 2003-11-09 , mais --preserve-rootn'est devenu la valeur par défaut dans cette validation 2006-09-03 , donc dans coreutils 6.2

FreeBSD a conservé la barre oblique depuis le commit du 10/10/2004 (avec un journal de commit "Découvrez à quel point mes sous-vêtements sont ignifugés" ), mais initialement pas quand il est sousPOSIXLY_CORRECT , jusqu'à ce qu'ils se souviennent de vérifier une décennie plus tard que POSIX était maintenant le mandant à quel point il a été fait également en mode POSIX .

La validation initiale de FreeBSD mentionne que Solaris le faisait déjà à ce moment-là.

@JdePB (dans le commentaire ci-dessous) a trouvé ce lien vers une histoire d'initié de Sun corroborant et donnant plus de détails sur l'origine de Solaris et suggérant que Solaris avait déjà la sauvegarde en place avant de faire la demande au groupe Austin.

Il explique la justification de l'ajout de cette exclusion. Bien que l'on ne puisse se blâmer que s'ils le font rm -rf /, il y a un cas où un script pourrait le faire s'il le fait rm -rf -- "$1/$2"sans vérifier cela $1/ qui a $2été fourni, ce qui a mal frappé certains clients Sun lors d'une mauvaise application d'un correctif Solaris (selon ce lien).

L'interdiction de la suppression de .et a ..été ajoutée bien avant cela et à nouveau pour se prémunir contre les accidents potentiels. rmest toujours une commande dangereuse. Il fait ce qu'il est censé faire: supprimer ce que vous lui dites.

rm -rf /*
cd /tmp &&  rm -rf .*/   # on some systems where rm -rf ../ still removes
                         # the content of ../ and shells that still
                         # may include . and .. in glob expansions.
rm -rf -- "$diretcory"/* # note the misspelled variable name
dir='foo '; rm -rf $dir/*

Serait également supprimer tout. La complétion du nom de fichier du shell est connue pour causer de tels problèmes lorsque vous le faites

rm -rf someth<Tab>/*

Développé à:

rm -rf something /*

Car somethingil se trouve que ce n'était pas un répertoire.

Les shells comme tcshou zshajouteront une invite supplémentaire lorsque vous essayez d'appeler rmavec un *caractère générique ( tcshpas par défaut).

Stéphane Chazelas
la source
1
En tant que jeune coopérative SA, j'ai essayé d'effacer les fichiers cachés dans le répertoire d'un utilisateur sur SunOS avec rm -rf .*son répertoire personnel. Peu de temps après, toutes les lignes téléphoniques se sont allumées ...
Aaron D. Marasco
Je parie $ rm -rf. * = Rm -rf / de façon compliquée pour y arriver.
Escoce
@GuruAdrian bien sûr, * signifie que tout correspond ainsi. * = .Filename mais aussi ../ et donc ../ .. et ../../ .. ad infinatum jusqu'à ce que vous manquiez d'espace de bits pour la commande.
Escoce
peut-être dans des coquilles modernes. Il n'en a pas toujours été ainsi. J'ai quitté cette profondeur de l'administration et du développement du système il y a plus de 15 ans
Escoce