Desde quando o POSIX e o GNU rm não excluem /?

24

Por vários anos, o utilitário rm do GNU não excluirá / , a menos que seja chamado com a opção --no-preserve-root . No entanto, o comando rm -rf / foi apresentado no subconsciente coletivo como perigoso por muito tempo e as pessoas ainda o citam como um comando "assustador".

Eu queria saber quando essa regra que rm não pode excluir / apareceu pela primeira vez. Eu verifiquei as especificações POSIX, e eu posso ver que, enquanto POSIX: 2008 inclui esse recurso de segurança, POSIX: 2001 não. Como as versões on-line das especificações POSIX são atualizadas de tempos em tempos, a cada novo sub-lançamento, eu também checava a máquina wayback e encontrei o página relevante do POSIX: 2008 de 2010 e conseguiu confirmar que a regra que rm não pode remover / já foi listado então.

Então, minhas perguntas são:

  • Quando foi a regra que rm não pode remover / adicionado às especificações POSIX? Foi na edição original de 2008 da Single UNIX Specification versão 4 ou foi adicionada em uma revisão?
  • Quando essa limitação foi adicionada ao GNU rm ? Tenho certeza que foi antes de ser adicionado ao POSIX, mas quando isso aconteceu?
por terdon 13.12.2017 / 23:47

1 resposta

29

Você pode encontrar a versão HTML de todas as edições do POSIX 2008 on-line:

Isso foi adicionado na edição de 2008.

A correção técnica geralmente não adiciona novos recursos.

Você pode ver que a versão anterior ( link ) (POSIX 2004) não tinha esse texto.

O novo texto foi aceito na conferência do grupo austin 2003-05-09 para inclusão em um revisão posterior da norma.

Foi solicitado por John Beck of Sun Microsystems em março do mesmo ano (link requer registro em grupo aberto, veja também Número do Pedido de Melhoria 5 aqui ).

John Beck wrote, on Tue 11 Mar 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 rm adicionado --preserve-root e --no-preserve-root opções em este commit de 2003-11-09 , mas --preserve-root somente se tornou o padrão em este 2006-09-03 commit , portanto em coreutils 6.2

O FreeBSD tem estado preservando a barra desde que 2004-10-04 cometer (com um "Descubra como a minha roupa interior à prova de chamas é realmente" log de envio), mas inicialmente não quando sob POSIXLY_CORRECT , até que se lembraram de verificar uma década depois que o POSIX estava agora mandando ponto em que foi feito também no modo POSIX .

As iniciais do FreeBSD confirmam que o Solaris já estava fazendo isso na época.

@JdePB (no comentário abaixo) descobriu que link para uma história de Sun insider corroborando e dando mais detalhes sobre a origem do Solaris e sugerindo que o Solaris já tinha a salvaguarda em vigor antes de fazer o pedido ao grupo de Austin.

Explica a razão para adicionar essa exclusão. Enquanto um só pode se culpar se eles fazem rm -rf / , há um caso em que um script poderia fazer isso se fazendo rm -rf -- "$1/$2" sem verificar que $1 / $2 foram fornecidos, o que é ruim para alguns clientes da Sun quando aplicação incorreta de um patch do Solaris (de acordo com esse link).

A proibição da exclusão de . e .. foi adicionada muito antes disso e novamente para salvaguardar contra possíveis contratempos. rm ainda é um comando perigoso. Ele faz o que deve: remover o que você diz.

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

Também removeria tudo. A conclusão do nome de arquivo do shell é conhecida por causar tais problemas quando você faz

rm -rf someth<Tab>/*

Expandido para:

rm -rf something /*

Porque something não era um diretório.

Shells como tcsh ou zsh adicionarão um prompt extra ao tentar chamar rm com um curinga * ( tcsh não por padrão).

    
por 14.12.2017 / 00:19