2017-02-05 12 views
0

Я смотрел на этих двух потоков для опорожнения каталога:Если я хочу очистить каталог, есть ли причина, по которой я не должен ее удалять и воссоздать?

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

Когда я думаю об удалении и добавлении каталога, я собираюсь сделать это на C и на платформе Linux. Однако, если вы хотите также объяснить причины этого в Windows, я тоже это оценю. Это код, который я бы реализовать:

system("rm -rf /some/directory") 
mkdir("/some/directory", 0700); 

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

ответ

4

Команда rm -fr /some/directory обязана выполнять рекурсивные работы. Использование команды намного проще, чем писать собственный код для выполнения той же работы - он воплощает достоинство лень и использует повторное использование кода в масштабе программы. (Вы не можете использовать системный вызов rmdir() в каталоге, если он уже не пуст.). Так что это не совсем необоснованно.

Одна проблема - безопасность: может ли кто-нибудь разместить альтернативу команде rm системы на вашем пути? В Unix есть /bin и /usr/bin сначала на вашем пути, или другие каталоги на первом месте?

Если вы решили, что использование /bin/rm (или /usr/bin/rm) достаточно безопасно, что может быть лучшим выбором, чем неукрашенная rm, но в целом, это не так уж плохо.

Другая проблема - это другой аспект безопасности - можете ли вы удалить и создать каталог? Можете ли вы написать в /some или нет? И следует ли сохранить текущего владельца, группу, разрешения /some/directory, если вы удалите и заново создадите его? После этих операций каталог будет принадлежать эффективному UID процесса; если будет принадлежать группе с эффективным GID процесса (если в каталоге /some нет липкого бита, или если вы не находитесь на macOS); и разрешения будут иметь значение 0777, измененное текущей установкой umask().

Если эти проблемы не важны или являются обходными, то удаление и воссоздание правдоподобно.


Расширение на вышеуказанные комментариях:

Когда вы упомянули system() вызов в своем комментарии, я понятия не имел, что вы говорили.

Функция system() выполняет строку, переданную в качестве аргумента с помощью командного интерпретатора. Когда вы пишете код, вы должны думать о том, как это может пойти не так, когда кто-то вредоносный пытается заставить вас запустить его.Когда вы пишете "rm -fr /some/directory", вы полагаетесь на оболочку, находя обычную команду rm и работая правильно. Однако, если ваш PATH имеет значение, такое как $HOME/bin:/bin:/usr/bin (так что команды в вашем собственном приватном каталоге bin используются в предпочтении к тем, которые предоставляются системой), то если пользователь может установить свой собственный скрипт как $HOME/bin/rm, они могут выполнять произвольный код с вашими привилегиями, которые могут позволить им оставить способ проникнуть в вашу систему, а затем сохранить все привилегии, которые у вас есть. Они могут даже очистить (большинство) доказательства того, что когда-то был сценарий $HOME/bin/rm.

Один из способов избежать такой проблемы является запрос "/bin/rm -fr /some/directory" (если rm не /usr/bin, а не в /bin, конечно). Это, возможно, безопаснее. Раньше были атаки, доступные через переменную окружения IFS; они стерилизованы современными оболочками, которые не используют никакого унаследованного значения для IFS.

Обратите внимание, что одна из проблем будет интерпретировать, была ли выполнена команда rm. Опция -fr означает, что она будет сообщать об успехе практически при любых обстоятельствах, но если каталог не исчезнет, ​​ваш вызов mkdir("/some/directory", 0777) завершится с ошибкой.

Что касается безопасности /some/directory, то мое понимание того, что вы пытаетесь сказать, заключается в том, что может быть выбран неправильный каталог. Я просто не могу представить, как это произойдет.

Предполагая, что ты есть разрешение на изменение /some каталога (вам это нужно, чтобы быть в состоянии удалить /some/directory), и что вы могли бы изменить все подкаталоги старой версии /some/directory, то вы можете начать off /some/directory принадлежит victim, группе witless и с разрешением 775, тогда как после команды и системного вызова (обратите внимание, что system() является функцией, а не системным вызовом, mkdir() - системный вызов), каталог может принадлежать пользователь victor, группа mischief и с разрешением 0777. Это может быть менее идеальным. Если вы не хотите нарушать такие параметры разрешения, вы, вероятно, не захотите использовать технику удаления и воссоздания - или, что не так просто, как показывает этот пример. Тогда вам придется немного усложнить удаление содержимого каталога без изменения этих атрибутов. Вы можете отсканировать каталог (opendir(), readdir(), closedir() и вызвать rm на каждое имя - или наборы имен - для тщательной очистки без удаления самой директории. Это сложная гибридность. Это более сложно, чем просто удаление и воссоздание, но гораздо менее затруднительно, чем иметь дело с полным рекурсивным удалением по нескольким уровням.

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

Помните, что если ваша программа может быть запущена с помощью root (administra tor), гораздо важнее быть осторожным - но это все равно имеет значение, даже если только обычные смертные пользователи будут запускать программу.

+0

Я все еще немного запутался в вашем объяснении безопасности, когда дело доходит до путей к файлу, но ваш ответ вполне достаточен для того, что я спросил, поэтому я буду отмечать его как официальный ответ. – Larrimus

+1

@ Larrimus: спасибо за прием. Какая часть «безопасности для путей к файлам» запутывает?Является ли это безопасностью 'system()' call и 'rm' или безопасностью'/some/directory', которую вы собираетесь удалить и воссоздать? Или оба...? –

+0

Я полагаю, это и то, и другое. Когда вы упомянули 'system()' звонок в своем комментарии, я понятия не имел, о чем вы говорите. Что касается безопасности '/ some/directory', то мое понимание того, что вы пытаетесь сказать, заключается в том, что может быть выбран неправильный каталог. Я просто не могу представить, как это произойдет. – Larrimus