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

81

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

Muye
источник
18
rm -rf /ничего не без удаления --no-preserve-root.
Муру
47
Моим самым первым опытом работы с Linux было создание Ubuntu vm, чтобы я мог "rm -rf /" его. Я рекомендую вам попробовать это. Его довольно быстро настроить, он обеспечивает безопасность вашего хоста и очень интересно наблюдать за тем, как различные части ОС рушатся на ваших глазах. Очень сытно.
DJMcMayhem
22
Напоминает мне мой любимый заниженный отчет об ошибке: bugzilla.redhat.com/show_bug.cgi?id=1202858 «Ожидаемые результаты: Squid перезапущен. Фактические результаты: все файлы удалены на машине».
9
Вы должны прочитать Unix Recovery Legend . Пока вы все еще вошли в оболочку, система не полностью мертва!
200_success
2
@gerrit я сделал . :)
Муру

Ответы:

79

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


Боковая панель / Update: За ответ Дэвида Hoelzer в (и упоминается в комментариях), инод HardLink /bin/rmиспользуется , чтобы указать будет оставаться вплоть до rmзаконченного (потому что Linux имеет место в открытом состоянии) , но этот факт не имеет значения; состояние диска вообще не имеет значения.

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

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


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

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

find / -exec rm {} \;

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

Оли
источник
7
Как объясняет @DavidHoelzer, несвязанные файлы не обязательно должны быть уже в памяти, чтобы продолжать работать. Ядро знает, что есть дескриптор открытого файла, поэтому оно хранит данные файла для удовлетворения любых запросов (включая вставки страниц), пока последний дескриптор не будет закрыт.
Эндрю Медико
4
@ Честно, нет, это не удастся, пока /bin/rmне будет достаточно близко, чтобы быть концом в самой последней партии; -exec ... {} +(экранирование обратной косой черты не требуется) все еще приводит к нескольким выполнениям; не по одному на файл, а по одному на пакет в зависимости от количества аргументов, которые могут поместиться в ARG_MAX.
Чарльз Даффи
6
@ Оли, это не пейджинг; счетчики ссылок связаны с индексом, а не с записью каталога, а дескриптор открытого файла считается ссылкой (так же, как жесткая ссылка), предотвращая освобождение индекса. Размер файла не имеет значения вообще, и это происходит, даже если нет места подкачки (таким образом, нет подкачки) вообще.
Чарльз Даффи
2
@CharlesDuffy Независимо от того, есть ли у вас место подкачки или нет, подкачка будет использоваться для всех файлов с отображенной памятью. Это включает в себя все исполняемые файлы и библиотеки. Фактически, отсутствие пространства подкачки может означать, что для отображаемых в память файлов файлов будет больше страниц.
Касперд
2
@CharlesDuffy Да, размер действительно не имеет значения. Отображение памяти в файле не приводит к загрузке содержимого файла до момента обращения к нему. Кроме того, память, используемая для загрузки частей файла, к которым осуществляется доступ, может быть при необходимости снова освобождена, после чего он будет загружен из файла при повторном доступе. Таким образом, файл действительно должен оставаться в файловой системе до тех пор, пока он отображается, и это ведет себя так же для одностраничного файла, как и для файла, достаточно большого, чтобы охватить все адресное пространство. (Подробности немного сложнее для отображений копирования при записи, которые необходимы для динамического связывания.)
kasperd
57

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

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

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

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

или же:

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

введите описание изображения здесь

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

Ошибка чтения из сокета: Сброс соединения по пиру

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

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

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

Там sudoтоже нет .

shutdown -h nowи rebootисчез, так что ваш единственный вариант - выключить машину вручную. Logout ( exit) не работает, даже если он показывает приятный текст «logout».

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

введите описание изображения здесь

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

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

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

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

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

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

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

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

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

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

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

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

Арсений Мурзенко
источник
VirtualBox поддерживает моментальные снимки диска.
Натан Осман
1
Обратите внимание, что вирусы часто предназначены для обнаружения виртуальных машин, поэтому я бы не советовал этот процесс обнаружения вирусов. Небольшой вопрос: эти оставшиеся четыре каталога не являются «настоящими» каталогами, верно? Они на самом деле не на жестком диске? Что остается на жестком диске после выполнения этой команды?
raptortech97
2
@ raptortech97 на rmсамом деле не стирает данные с жесткого диска, а просто «отсоединяет» (разъединяет) фактические данные на диске от дерева файловой системы, помечая их как свободные (чтобы они могли в конечном итоге перезаписаться при обычном использовании компьютера). Так что, если вы, скажем, rm -rf ~не все потеряно, пока вы действуете быстро (например, с помощью extundelete). Вы можете думать об этом как о еще более ненадежной версии «удаленной» папки в вашем почтовом ящике, вы можете получить материал обратно, если не будете ждать слишком долго, но в конечном итоге он будет очищен.
Томас
@ raptortech97 С другой стороны, если по какой-то причине вы не использовали, rmно shredигра в значительной степени окончена, хотя у вас, вероятно, будет время осознать свою ошибку и прервать ее, поскольку уничтожение занимает больше времени.
Томас
5
Сохраняемые каталоги, скорее всего, являются точками монтирования той или иной формы. И команды, которые продолжают работать, являются встроенными командами bash, а не отдельными двоичными файлами. Так что пока lsнет, for i in /*; do echo $i; doneдолжно работать. И для замены catвы можете использовать команду, как while read i; do echo $i; done < /proc/self/maps.
MvG
25

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

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

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

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

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

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

Дэвид Хоэлзер
источник
Иными словами, количество ссылок не равно нулю, потому что открытие файла добавляет ссылку в / proc.
OrangeDog
@OrangeDog, это поведение все еще существует, даже если procfs отключен.
Чарльз Даффи
1
@OrangeDog Чарльз Даффи прав. Дескрипторы файла в / proc не изменяют inode, регулируя количество ссылок.
Дэвид Хоэлзер
/ proc и / sys являются отражением текущего состояния системы (ядра). Только выбор действий с файлами и каталогами в них фактически изменяет состояние системы.
CVn
18

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

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

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

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

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

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

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

Алексей Каменский
источник
В Linux вы, безусловно, можете удалять узлы устройства при запуске от имени пользователя root. Но да, вы не можете ничего удалить из, /procпоскольку это файловая система только для чтения. Аналогично для /sys. Я считаю, что вы также не можете удалить точки монтирования.
Брайан
@AlexKey Я предлагаю редактирование, чтобы уточнить, что вы подразумеваете под «не встроенной в ядро ​​командой» (или вообще избегать этой фразы). Похоже, вы говорите, что есть команды, которые вы можете запустить через оболочку, которые реализованы непосредственно в ядре, поэтому они всегда работают независимо от того, что. (Что, как вы, вероятно, знаете, но многие читатели могут и не знать, не тот случай: когда вы запускаете такую ​​команду cd, она вызывает встроенную оболочку с таким именем - эта команда встроена в оболочку, а не в ядро.) значит Alt + SysRq "команды"?
Элия ​​Каган
@ Брайан, это зависит от дистрибутива? Я работал в разных дистрибутивах, и, как ни странно, эта ошибка повторялась несколько раз. Как я вспомнил после проверки остатков / в / dev все еще было что-то, но это могли быть такие вещи, как cdrom или дискета ...
Алексей Каменский
@EliahKagan Когда я пытался оставаться независимым от дистрибутива, я использовал этот термин. Это означает, что не во всех системах команда cli означает внешнюю программу. Но спасибо, что указал на это, я проясню вопрос.
Алексей Каменский
@AlexKey Я думаю, вы не сможете удалить, /dev/ptsтак как это точка монтирования. (И файловая система только для чтения тоже.)
Brian
1

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

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

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

s1mmel
источник
4
Почему ядро ​​застряло? Ответ от MainMa предполагает иное, и поддерживает то, что я ожидал.
MvG
4
Программы запускаются из памяти, а не с жесткого диска. Ядро не узнает ничего плохого до перезагрузки.
phyrfox
Ну, может, мне нужно изменить слова, которые я использовал, ядро ​​более или менее «зависло» без устройств, программ и т. Д., И если вы не находитесь перед корневой консолью, вы не можете делать плохие вещи, черт возьми, даже на этом утешить, вы не можете делать плохие вещи. Но я изменю свою формулировку в своем ответе, поскольку она вводит в заблуждение, я согласен.
s1mmel
0

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

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

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

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

Более поздние версии Android поддерживают Selinux именно по этой причине.

Марк Аллин
источник