Как «rm -rf /» может удалить все файлы в системе?

78

Я не пробовал эту команду на Ubuntu (по понятным причинам), поэтому я не уверен, разрешит ли Ubuntu его выполнение. Но он известен тем, что удаляет все. Просто из любопытства, что происходит, когда ядро ​​и /bin удалены? Как rm поддерживает стек времени выполнения? Как rm удается обмениваться файловой системой с полным удалением? Как он взаимодействует с оборудованием?     

задан Muye 02.04.2015 в 10:13
источник

6 ответов

74

Не имеет значения, что /bin/rm удаляется. Он запускается только один раз, и к этому моменту все загружается в память, как и все остальное, необходимое для отправки удалений в файловую систему и диск.

Боковая панель / Обновление: В ответе Дэвида Хольцера (и упоминается в комментариях), индекс inode, на который ссылается hardlink /bin/rm , останется до тех пор, пока rm не закончит (поскольку Linux держится в открытом состоянии) , но , этот факт не имеет значения; состояние диска вообще не имеет значения.

Двоичный файл загружается в память до его запуска. Даже если вы можете вручную уничтожить данные диска rm , это не повлияет или не прекратит удаление из-за завершения (если вы не сделаете иначе, что диск недоступен).

Не знаете, что такое inode или hardlink? Это ответ, когда я его разработал.

В любом случае, именно поэтому вы можете удалить пакет для ядра current без компьютерного взрыва. Пока вы устанавливаете другую версию, она сможет загрузиться.

Опять же, это работает, потому что rm вызывается только один раз. Следующие будут терпеть неудачу после того, как /bin/rm умер, потому что он называет его один раз для каждого имени файла:

find / -exec rm {} \;

Тем не менее, find / -exec rm -rf {} + и find / -print0 | xargs -0 rm -rf также могут потерпеть неудачу, потому что они оба имеют ограничения по аргументам, то есть они будут удалять только несколько файлов перед их повторным вызовом. В какой-то момент пути /bin/rm может истечь ( и ) до того, как остальные файлы будут удалены. Однако это не гарантировано. Если /bin/ были последним введенным каталогом, эти методы могли бы работать.

    
ответ дан Oli 02.04.2015 в 10:26
источник
53
  

Я не пробовал эту команду на Ubuntu (по понятным причинам), поэтому я не уверен, разрешит ли Ubuntu его выполнение.

Я сделал. rm -rf / --no-preserve-root выполнялось в корневом сеансе, открывшемся непосредственно на машине, тогда как я также был подключен через ssh с другого компьютера, используя также учетную запись root.

Что происходит, так это то, что вы начинаете получать много таких сообщений, как:

  

rm: не удается удалить '/ ...': операция не разрешена

или

  

rm: не удается удалить "/ ...": занято устройство или ресурс

Удивительно, что соединение ssh оставалось открытым до конца операции. Только когда я закрыл соединение и попытался снова открыть его, появилась ошибка:

  

Чтение с сокета не выполнено: сброс соединения с помощью peer

На машине остаются четыре каталога:

  • /dev . Здесь хранятся файлы устройств.
  • /proc - файловая система в памяти, созданная ядром.
  • /run , стандартизованное расположение файловой системы для демонов.
  • /sys . Это позволяет получить информацию о системе и ее компонентах.

Это означает, что осталось немного и не так много сделать. Вы не можете ls (хотя при использовании Tab имена каталогов и файлов все еще отображаются). Вы можете cd в разных каталогах, а также echo , но команды, такие как cat , больше не доступны.

Не существует sudo .

shutdown -h now и reboot также исчезли, поэтому ваш единственный вариант, похоже, выключает машину вручную. Выход из системы ( exit ) не работает, даже если он показывает хороший текст "выхода".

Как только вы попытаетесь перезагрузить компьютер, вам будет предоставлена ​​хорошая ошибка GRUB 15, а затем ничего не произойдет, и в этот момент вы можете начать думать, что ваш rm мог сделать что-то плохое в вашей системе.

Вы можете сделать это тоже

Нет, подождите, не делайте этого на своей машине!

Вместо этого вы можете запустить виртуальную машину . У виртуальных машин есть преимущество, позволяющее сделать эксперименты очень легкими. Поскольку вы используете Ubuntu, вас может заинтересовать vmbuilder . Это инструмент, который позволяет вам развернуть виртуальные машины за считанные минуты (официальная документация утверждает, что это можно сделать "через минуту", но фактическое время, даже на быстром аппаратном обеспечении, составляет более двух-трех минут .

После завершения развертывания у вас есть среда, с которой вы можете играть. Если вы в конечном итоге уничтожаете его, это не имеет значения: вы снова развертываете машину, а две минуты позже можете продолжить.

Если вы используете программное обеспечение, такое как VMWare, вы также можете быть заинтересованы в моментальных снимках (обратите внимание, что бесплатный проигрыватель VMWare не имеет этой функции, вам необходимо приобрести VMware Workstation). Обратите внимание, что Hyper-V является бесплатным и поддерживает моментальные снимки (но вы должны запускать Windows).

Преимущество моментальных снимков заключается в том, что вы можете взять один за миллисекунды. Возврат к снимку занимает больше времени, но часто это вопрос секунд. Это упрощает и ускоряет эксперименты.

Это экспериментирование не ограничивается самой операционной системой. Вы можете делать все, что связано с программным обеспечением. Получил подозрительное заявление? Протестируйте его в виртуальной машине - если это вирус, это не повредит. Хотите протестировать операцию в базе данных, учитывая, что она может повлиять на окружающую среду? Проверьте его на виртуальной машине.

Что делать, если вы сделали это на реальной, не тестируемой машине?

Плохие вещи случаются. Обратите внимание, что rm защищает вас от вас: rm -rf / не работает: вам нужно использовать --no-preserve-root . Тем не менее, что, если вы на самом деле достигли, по ошибке, удалить все?

rm только отключает файлы , но данные все еще присутствуют на вашем жестком диске. Это позволяет восстановить его позже (поэтому вы не должны просто бросать свои жесткие диски с конфиденциальными данными, если они больше не работают).

Это означает, что вам просто нужно иметь запасной ПК с корпусом жесткого диска, чтобы фактически восстановить файлы размером all . Важно не записывать что-либо на жесткий диск для восстановления: записываемые данные перезаписывают несвязанные файлы.

Как отмечается в статье в комментарии 200_success , если вы действуете умным , вы можете вернуть машину даже без запасного ПК. Если вам нужны только данные, я бы не стал беспокоиться - восстановление его с помощью запасного ПК намного проще.

    
ответ дан Arseni Mourzenko 02.04.2015 в 20:06
25

Причина в том, что слой имен файлов (то, что вы видите с ls ) действительно просто для вашего удобства. Драйвер файловой системы и ядро ​​заботятся только о том, что такое inode. Когда файл ссылается по имени, он немедленно переводится в индекс, содержащий все метаданные, включая разрешения, блоки данных на диске, идентификатор владельца, идентификатор группы и количество ссылок.

Здесь действительно важна ссылка. Когда вы удаляете файл в системе UNIX, фактический системный вызов - это unlink . Что происходит под капотом, так это то, что количество ссылок (количество имен файлов в слое имен файлов), указывающее на этот индекс, уменьшается. Файловая система знает, что файл удаляется, когда количество ссылок достигает нуля.

Когда файл удаляется rm , он также редактирует файл каталога (да, это просто файл, который содержит имя файла и inode, а также несколько других битов, которые не важны для этого ответа). Однако это отключение, которое фактически освобождает дисковые ресурсы.

Это приводит к некоторым другим интересным эффектам. Во-первых, можно открыть файл, число ссылок которого равно нулю. Это происходит, когда rm -rf / удаляет запись для /bin/rm . Файл открыт (для него есть дескриптор файла), но inode помечен как удаленный (ссылка count = 0). Ресурсы диска не будут выпущены и повторно использованы до тех пор, пока дескриптор файла не будет закрыт.

Другим интересным эффектом является то, что происходит, когда у вас есть индекс inode с номером ссылки больше нуля, но ничего не отображается в слое имен файлов, который указывает на него. Это, в некотором смысле, очень хорошо скрытый файл :). Чтобы получить доступ к нему, вам нужно будет использовать что-то низкое, чтобы ссылаться на него по номеру inode, а не по имени (потому что его нет) или редактировать запись в каталоге, чтобы указывать на индекс с помощью шестнадцатеричного редактора.

Третий интересный эффект - это то, что произойдет, если вы уменьшите количество ссылок до нуля, но все равно укажите запись в каталоге inode. Я оставлю это вам, чтобы поэкспериментировать, если хотите. Ясно, однако, что эти последние два приводят к тому, что файловая система находится в несогласованном состоянии.

    
ответ дан David Hoelzer 02.04.2015 в 15:08
17

Предыдущие ответы хороши, но я хочу уточнить одну деталь:

rm - это не просто команда. Это программа, которая находится в PATH .

Поэтому то, что происходит при выполнении, следующее:

  • вы вызываете (как root) rm -rf /
  • экземпляр программы rm загружается в память аргументами -rf и /
  • на основе этих аргументов программа rm запускает свои операции (проходит через все в mount / partition и рекурсивно удаляет ссылки на нее [извините за техничность;)])
  • Как только он будет завершен, экземпляр программы rm будет выгружен
  • в этот момент единственными вещами в памяти являются ранее загруженные программы (например, bash, если у вас открыт терминал в среде Ubuntu, Desktop, ядре, драйверах и т. д.).
  • , если вы попытаетесь вызвать любую другую команду (которая в случае, если Linux делает ее автономной программой), она потерпит неудачу, потому что такой программы не обнаружено в местах PATH (а местоположения PATH больше не существуют). Однако все загруженные все еще будут выполняться

Просто для того, чтобы понять, как это работает, попробуйте установить LAMP на ubuntu (в Virtualbox), некоторый кеш-код сценария и PHP, затем вызовите эту команду зла. Удивительно (если вам повезло, и ваш кеш кода операции не заметил удаления файла php), вы все равно можете получить доступ к скриптам php извне через веб-сервер apache!

PS: эта команда зла даже запускалась, поскольку root не удаляет everything , она не может удалить некоторые привилегированные процессы из /proc и не может удалить некоторые вещи из /dev устройств, которые появляются в вашей системе как файлы. На самом деле, корень не настолько всемогущ, как мы думаем, ядро ​​с другой стороны.

PPS: Также как вторая мысль, вы также будете иметь файлы, которые были locked другим процессом во время попытки удаления.

    
ответ дан AlexKey 02.04.2015 в 13:45
1

Как только все вытолкнуто с жестких дисков, ядро ​​все еще работает, но вроде застряло, поскольку никаких устройств и программ, команд и т. д. не осталось.

ОС больше не будет работать.

И это правда, что говорит Оли, команда загружается / выполняется в память, и ничто не остановит ее, если вы не убьете этот процесс (конечно, если команда kill все еще присутствует ^^).

    
ответ дан s1mmel 02.04.2015 в 11:35
0

Имейте в виду, что если система имеет selinux и selinux в режиме принудительного исполнения, а политики selinux настроены правильно; то ничего не произойдет.

Selinux - это обязательный контроль доступа, что означает, среди прочего, что у пользователя root не так много сил для разрушения системы, чем у любого другого пользователя в системе.

Selinux применяется в ядре; вам придется скомпрометировать ядро, чтобы обойти его.

В хорошо спроектированной системе с хорошими политиками Selinux root не сможет многое сделать в системе.

Более поздние версии Android имеют Selinux, обеспечивающие только по этой причине.

    
ответ дан Mark Allyn 03.04.2015 в 04:38