access () Отверстие - PullRequest
       21

access () Отверстие

3 голосов
/ 28 октября 2011

Я занимался написанием оболочки и наткнулся на рекомендацию для access () проверить, существует ли файл, можно ли его прочитать и т. Д. Кажется, что это очень просто реализовать и быстрее, чем stat ().Когда я начал просматривать страницу руководства, я заметил, что она НЕ рекомендуется для использования, поскольку это может привести к дыре в безопасности.Страница man говорит следующее:

Использование access () для проверки того, авторизован ли пользователь, например, открыть файл, прежде чем делать это, используя open (2), создает дыру в безопасности, потому что пользователь может использоватькороткий промежуток времени между проверкой и открытием файла для манипулирования им.

Кто-нибудь знает, как это можно использовать или это относится только к использованию open () после проверки файла?Я знаю, что многие говорят, что вместо этого нужно использовать stat (), но access () так просто реализовать, особенно для оболочки, для которой я его использовал.

Спасибо

Ответы [ 3 ]

5 голосов
/ 28 октября 2011

Это гонка TOCTOU (время проверки к времени обновления). Злонамеренный пользователь может заменить файл, к которому у него есть доступ, символической ссылкой на то, к чему у него нет доступа между вызовами access() и open(). Используйте faccessat() или fstat(). Как правило, откройте файл один раз и используйте для него функции f*() (например, fchown(), ...).

0 голосов
/ 28 октября 2011

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

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

0 голосов
/ 28 октября 2011

Одна вещь, о которой я могу думать, хотя она кажется слабой - 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
...