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
Другие вопросы по тегам