Da quando POSIX e GNU rm non cancellano /?


23

Da diversi anni, l' rmutilità GNU non verrà eliminata /se non viene chiamata con l' --no-preserve-rootopzione. Tuttavia, il comando rm -rf /è stato presentato nel subconscio collettivo come pericoloso per molto tempo e la gente lo cita ancora spesso come un comando "spaventoso".

Mi chiedevo quando apparve per la prima volta questa regola che rmnon è possibile eliminare /. Ho controllato le specifiche POSIX e posso vedere che mentre POSIX: 2008 include questa funzione di sicurezza, POSIX: 2001 no. Poiché le versioni online delle specifiche POSIX vengono aggiornate di volta in volta, con ogni nuova versione secondaria, ho anche controllato la macchina di ritorno e ho trovato la pagina pertinente di POSIX: 2008 dal 2010 e sono stato in grado di confermare che la regola che rmnon è possibile rimuovere /era già elencato allora.

Quindi, le mie domande sono:

  • Quando è stata aggiunta la regola che rmnon è possibile rimuovere /alle specifiche POSIX? Era nell'edizione originale 2008 della versione 4 della specifica UNIX singola o è stato aggiunto in una revisione?
  • Quando è stata aggiunta questa limitazione a GNU rm? Sono abbastanza sicuro che fosse prima che fosse aggiunto a POSIX, ma quando è successo?


1
Correlati: Austin Group Interpretation # 019 (2003), che ha descritto (ma non implementato) il cambiamento.
Michael Homer,

Risposte:


28

Puoi trovare la versione HTML di tutte le edizioni di POSIX 2008 online:

È stato aggiunto nell'edizione 2008.

Le rettifiche tecniche generalmente non aggiungono nuove funzionalità.

Puoi vedere la versione precedente ( http://pubs.opengroup.org/onlinepubs/009695399/utilities/rm.html ) (POSIX 2004) non aveva quel testo.

Il nuovo testo è stato accettato nella conferenza del gruppo austin del 2003-05 per l'inclusione in una successiva revisione dello standard.

È stato richiesto da John Beck di Sun Microsystems a marzo dello stesso anno (il collegamento richiede la registrazione del gruppo operativo, vedere anche la Richiesta di miglioramento numero 5 qui ).

John Beck ha scritto, martedì 11 marzo 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 ha rmaggiunto --preserve-roote --no-preserve-rootopzioni in questo commit 2003-11-09 , ma è --preserve-rootdiventato solo il default in questo commit 2006-09-03 , quindi in coreutils 6.2

FreeBSD ha preservato la barra da quel commit del 2004-10-04 (con un registro di commit "Scopri quanto sono resistenti le mie mutande" ), ma inizialmente non quando era sottoPOSIXLY_CORRECT , fino a quando non si sono ricordati di controllare un decennio dopo che POSIX era ora obbligandolo a quel punto è stato fatto anche in modalità POSIX .

Il commit iniziale di FreeBSD menziona che Solaris lo stava già facendo in quel momento.

@JdePB (nel commento sotto) ha trovato quel collegamento a una storia di insider Sun che conferma e fornisce maggiori dettagli sull'origine di Solaris e suggerisce che Solaris aveva già messo in atto la protezione prima di presentare la richiesta al gruppo di Austin.

Spiega la logica per l'aggiunta di tale esclusione. Mentre si può incolpare se stessi solo se lo fanno rm -rf /, c'è un caso in cui uno script potrebbe farlo se lo fa rm -rf -- "$1/$2"senza controllare $1/ $2sono stati forniti che è la cosa che colpisce alcuni clienti Sun quando si applica erroneamente una patch Solaris (secondo quel link).

La proibizione della cancellazione di .ed è ..stata aggiunta molto prima e ancora per salvaguardarsi da potenziali incidenti. rmè ancora un comando pericoloso. Fa quello che deve fare: rimuovi ciò che gli dici.

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/*

Rimuoverebbe anche tutto. È stato risaputo che il completamento del nome file Shell causa tali problemi

rm -rf someth<Tab>/*

Espanso a:

rm -rf something /*

Perché somethingcosì è successo non essere una directory.

Conchiglie come tcsho zshaggiungeranno un ulteriore prompt quando si tenta di chiamare rmcon un *carattere jolly ( tcshnon per impostazione predefinita).



1
Come giovane SA cooperativa, ho provato a cancellare i file nascosti nella directory di un utente su SunOS con la rm -rf .*sua home directory . Poco dopo, tutte le linee telefoniche si accesero ...
Aaron D. Marasco il

Scommetto $ rm -rf. * = Rm -rf / in modo contorto per arrivarci.
Escoce,

@GuruAdrian certo, * significa abbinare tutto così. * = .Filename ma anche ../ e quindi ../ .. e ../../ .. ad infinatum fino a quando non si esaurisce lo spazio bit per il comando.
Escoce,

forse nelle conchiglie moderne. Non è stato sempre così. Ho lasciato quella profondità di amministrazione e sviluppo del sistema più di 15 anni fa
Escoce il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.