Приложение хочет проанализировать и «выполнить» файл и хочет подтвердить, что файл является исполняемым по соображениям безопасности.
Подумав несколько мгновений, вы поймете, что у этого исходного кода есть условие гонки, которое делает схему безопасности неэффективной:
import os
class ExecutionError (Exception):
pass
def execute_file(filepath):
"""Execute serialized command inside @filepath
The file must be executable (comparable to a shell script)
>>> execute_file(__file__) # doctest: +ELLIPSIS
Traceback (most recent call last):
...
ExecutionError: ... (not executable)
"""
if not os.path.exists(filepath):
raise IOError('"%s" does not exist' % (filepath, ))
if not os.access(filepath, os.X_OK):
raise ExecutionError('No permission to run "%s" (not executable)' %
filepath)
data = open(filepath).read()
print '"Dummy execute"'
print data
Состояние гонки существует между
os.access(filepath, os.X_OK)
и
data = open(filepath).read()
Поскольку существует вероятность того, что файл будет перезаписан неисполняемым файлом разного содержимого между этими двумя системными вызовами.
Первое решение, которое у меня есть, это изменить порядок критических вызовов (и пропустить проверку избыточности, которая теперь избыточна):
fobj = open(filepath, "rb")
if not os.access(filepath, os.X_OK):
raise ExecutionError('No permission to run "%s" (not executable)' %
filepath)
data = fobj.read()
Решает ли это состояние гонки? Как я могу решить это правильно?
Обоснование схемы безопасности, кратко (подумал я)
Файл сможет выполнять произвольные команды внутри
окружение, поэтому оно сопоставимо со сценарием оболочки.
На свободных рабочих столах была дыра в безопасности с файлами .desktop, определяющими
Приложения: файл может указывать любой исполняемый файл с аргументами, и
он может выбрать свой собственный значок и имя. Таким образом, случайно скачанный файл может скрыть
за любое имя или значок и делать что-нибудь. Это было плохо.
Это было решено требованием, чтобы файлы .desktop имели исполняемый бит
установить, иначе они не будут отображаться с именем / значком и бесплатным рабочим столом
спросит пользователя, хочет ли он запустить программу перед началом.
Сравните это с очень хорошим дизайном Mac OS X: "Эта программа была загружена из Интернета,
Вы уверены, что хотите открыть его? ".
Так что в иносказании это и тот факт, что вы должны chmod +x
оболочки
Скрипты, которые вы скачиваете, я думал о дизайне в вопросе выше.
Заключительные слова
Может быть, в заключение, может быть, нам следует сохранить его простым: если файл должен быть исполняемым, сделайте его исполняемым и дайте ядру выполнить его при вызове пользователем. Передача задачи тому, кому она принадлежит.