Понимание ядра Linux говорит о реализации execve()
:
do_execve( )
выполняет следующие операции:
Динамически выделяет linux_binprm
структура данных, которая будет заполнена данными, касающимися нового исполняемого файла.
Вызывает path_lookup(), dentry_open()
и path_release()
для получения объекта dentry, объекта файла и индексаобъект, связанный с исполняемым файлом.В случае ошибки возвращается правильный код ошибки.
Проверяет, что файл является исполняемым текущим процессом ;также проверяет, что файл не записывается, просматривая поле i_writecount
в inode
;хранит -1 в этом поле, чтобы запретить дальнейший доступ для записи.
В многопроцессорных системах он вызывает функцию sched_exec()
, чтобы определить наименее загруженный ЦП, который может выполнять новую программу, и выполнить миграцию.текущий процесс к нему (см. главу 7).
Вызывает init_new_context()
, чтобы проверить, использовал ли текущий процесс пользовательскую таблицу локальных дескрипторов (см. раздел «LDT Linux» вГлава 2);в этом случае функция выделяет и заполняет новый LDT для использования новой программой.
Вызывает функцию prepare_binprm( )
для заполнения структуры данных linux_binprm
.Эта функция, в свою очередь, выполняет следующие операции:
a. Еще раз проверяет, является ли файл исполняемым (установлено хотя бы одно право доступа на выполнение) ;если нет, возвращает код ошибки.( Предыдущая проверка на шаге 3 недостаточна , поскольку процесс с набором возможностей CAP_DAC_OVERRIDE
всегда удовлетворяет проверке; см. Раздел «Учетные данные и возможности процесса» ранее в этой главе).
...
Выполняют ли шаг 3 и шаг 6a проверку, что бит разрешения на выполнение исполняемого файла установлен для процесса?
Каковы их различия и отношения?
Не учитывает ли шаг 3 производительность процесса CAP_DAC_OVERRIDE
, а шаг 6a -?Является ли это единственной разницей между двумя шагами?
Зачем нам нужна двухэтапная проверка, а не одноэтапная проверка путем объединения всех проверок в шаг 3 или шаг 6a?
Спасибо.