access() Отверстие
Я занимался написанием оболочки и наткнулся на рекомендацию для access() проверить, существует ли файл, можно ли его прочитать и т. Д. Кажется, что это очень просто реализовать и быстрее, чем stat(). Когда я начал просматривать страницу руководства, я заметил, что она НЕ рекомендуется для использования, потому что это может привести к дыре в безопасности. Страница руководства говорит это:
Использование access() для проверки того, авторизован ли пользователь, например, на открытие файла, прежде чем делать это с помощью open(2), создает дыру в безопасности, поскольку пользователь может использовать короткий промежуток времени между проверкой и открытием файла, чтобы манипулировать им.
Кто-нибудь знает, как это можно использовать или это относится только к использованию open() после проверки файла? Я знаю, что многие говорят, что вместо этого нужно использовать stat (), но access() так просто реализовать, особенно для оболочки, для которой я его использовал.
Спасибо
3 ответа
Это гонка TOCTOU (время проверки к времени обновления). Злонамеренный пользователь может заменить файл, к которому у него есть доступ, символической ссылкой на то, к чему у него нет доступа между access()
и open()
звонки. использование faccessat()
или же fstat()
, В общем, откройте файл один раз и используйте f*()
функции на нем (например: fchown()
...)
Шаблон, кажется, зовет access()
или же stat()
чтобы определить, можете ли вы открыть файл, а затем открыть его, если у вас есть разрешение.
Вместо этого обычно лучше просто попытаться открыть его, а затем проверить, была ли попытка успешной (и если нет, то почему). Это позволяет избежать временного интервала между проверкой и попыткой открыть файл.
Я могу придумать одну вещь, хотя она кажется слабой - access() использует реальные, а не эффективные uid и gid. Предположительно, это позволяет программе setuid (которая выполняется обычным пользователем, но получает разрешения владельца), чтобы проверить, может ли вызывающий пользователь прочитать файл, чтобы предотвратить непреднамеренное предоставление этому пользователю доступа к файлу, который он не сможет прочитать, возможно, с помощью какой-нибудь символической ссылки или хитрого трюка с ссылками. Я не могу найти никаких доказательств того, что это возможно, или что это невозможно с помощью stat(), но представьте себе такой сценарий:
user executes program
program is setuid, immediately gets all privs of root
program checks file1 to ensure that user has access
file1 is a hardlink to file2, which user has access to
user changes file1 to hardlink to file3 (/etc/shadow or something like that)
program reads file1 and does something to it (print, convert, whatever)
user now has access to a file they shouldn't