Как ядро ​​Linux знает, что адрес, переданный в качестве аргумента в syscall, неверен? - PullRequest
0 голосов
/ 13 мая 2018

В настоящее время я читаю Системные вызовы главу Понимание ядра Linux и я не могу понять тот факт, что ядро ​​Linux знает адресный аргумент, переданный через syscall (), недопустим.

Book упомянул, что проверка адреса откладывается до тех пор, пока он не будет использован, и когда linux использует этот адрес, он генерирует ошибку страницы.Далее упоминалось, что в трех случаях в режиме ядра может произойти сбой

• Ядро пытается обратиться к странице, принадлежащей адресному пространству процесса, но либо соответствующий фрейм страницы не существует, либо ядропытается написать страницу только для чтения.

• В некоторых функциях ядра имеется программная ошибка, приводящая к возникновению исключения при выполнении этой программы;в качестве альтернативы исключение может быть вызвано временной аппаратной ошибкой.

• Подпрограмма службы системных вызовов пытается выполнить чтение или запись в область памяти, адрес которой был передан в качестве параметра системного вызова, но этот адрес непринадлежат к адресному пространству процесса.

Эти случаи должны различаться обработчиком ошибок страницы, поскольку выполняемые действия весьма различны. Обработчик ошибок страницы может легко распознать первый случай, определив,неправильный линейный адрес включен в одну из областей памяти, принадлежащих процессу.

Но как ядро ​​различает оставшиеся два случая.Хотя это объяснено в учебнике, но мне оно кажется чуждым.Пожалуйста, помогите и объясните.

1 Ответ

0 голосов
/ 15 мая 2018

Обработчик ошибок страницы __do_page_fault включает в себя этот фрагмент кода:

if (!(error_code & X86_PF_USER) &&
            !search_exception_tables(regs->ip)) {
            bad_area_nosemaphore(regs, error_code, address, NULL);
            return;
        }

Это условие !(error_code & X86_PF_USER) выполняется, когда системный вызов происходит из режима ядра, а не из режима пользователя.Это условие !search_exception_tables(regs->ip) истинно, когда сбой страницы не произошел из-за выполнения одной из инструкций, использующих линейную функцию, переданную системному вызову.Обратите внимание, что regs->ip содержит указатель команды, вызвавшей ошибку страницы.Если оба эти условия выполняются, это означает, что в какой-либо функции ядра имеется ошибка или имеется какая-то аппаратная ошибка (второй случай).

regs содержит снимок всех архитектурных регистров ввремя ошибки страницы.На x86 это включает в себя регистр сегмента CS.RPL в этом регистре можно использовать для определения того, произошел ли системный вызов из пользовательского режима или режима ядра.

search_exception_tables выполняет двоичный поиск по отсортированным массивам адресов команд, которые создаются во время компиляции при компиляцииядро.Это в основном инструкции для доступа к адресу, переданному системному вызову.

Для двух других перечисленных вами случаев условие !(error_code & X86_PF_USER) будет ложным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...