Реальный пример о границе защиты ОС? - PullRequest
1 голос
/ 17 июня 2020

Я пытаюсь понять, как границы между пользователем и ядром работают в операционных системах.

Я читал об этом, и мне кажется, что если что-то на уровне пользователя попытается выполнить запрещенное действие, оборудование будет запустить ловушку и отправить управление обратно в ОС на уровне ядра, и ядро ​​справится с этой ситуацией.

Как это вообще возможно? Как может что-то go напрямую с уровня пользователя на аппаратное обеспечение, не все взаимодействия выполняются через системные вызовы (которые находятся на уровне ядра)? Тогда ядро ​​будет предугадывать, является ли действие незаконным или нет. мне понять, если кто-то может это сделать, я был бы очень признателен

1 Ответ

2 голосов
/ 17 июня 2020

Как может что-то go напрямую с уровня пользователя на оборудование, не все взаимодействия осуществляются посредством системных вызовов (которые находятся на уровне ядра)?

Многие взаимодействия не выполняются через системные вызовы. Для практического примера; на 80x86 вещи, которые могут вызвать переключение от пользователя к ядру:

a) Любое прерывание, которое включает:

  • любое исключение (исключение отладки, разделение исключения, недопустимое исключение кода операции, ошибка общей защиты, ошибка страницы, исключение проверки машины, ...). Они указывают на программные ошибки (например, деление на ноль) или аппаратные сбои (исключение машинной проверки), или возможности ядра для расширения функциональности (например, сбой страницы, указывающий, что ядру необходимо получить данные из области подкачки, потому что ядро ​​увеличивает объем «памяти») программы могут использовать, et c).

  • любое прерывание (от устройства, запрашивающего внимание)

  • любое прерывание, отправленное от (программное обеспечение / ядро, работающее на) от одного ЦП к другому ЦП

  • программные прерывания (от одного ЦП)

б) Определенные специальные инструкции (обычно используемые для точки входа в API ядра):

  • SYSCALL, SYSENTER

  • «дальний вызов» или «дальний вызов jmp», который включает в себя вызов шлюз или шлюз задачи

  • программные прерывания (от того же ЦП). Упоминается дважды, потому что подходит для обеих категорий.

Обратите внимание, что ядро ​​может предоставлять несколько точек входа по разным причинам (например, одна для 64-битных процессов, а другая для 32-битных процессов или может быть, один для всех процессов и другой, который может использоваться только специальными / доверенными процессами, или один быстрый, но большой для часто исполняемого кода, а другой маленький, но медленный для уменьшения размера кода в редко выполняемом коде, или ...); и может использовать прерывание (например, исключение - раньше я использовал «исключение точки останова») вместо или в дополнение к специальной инструкции для API ядра.

Все эти вещи имеют две общие характеристики - все они вызывают / позволяют пересечь «границу между уровнем пользователя и ядром»; и расположение кода, которому передается управление, определяется ядром, а не вызывающей стороной (кодом уровня пользователя), так что ядро ​​может защищать / защищать все свои точки входа.

Также обратите внимание, что в некоторых в этих случаях (IRQ, исключение проверки машины) отвечает оборудование, а не программное обеспечение. Это важно / необходимо для обеспечения своевременного внимания к оборудованию (например, злонамеренный процесс «отказа в обслуживании» не может просто выполнить бесконечное число l oop, чтобы ядро ​​не использовало ЦП, что вы и сделали бы получить, если системные вызовы были единственным способом пересечь границу пользователя / ядра).

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

Для примера того, что может произойти, когда (пользовательский) процесс запущен; программа может выполнить некоторый код (а затем попытаться получить доступ к некоторым данным, которых на самом деле нет в ОЗУ, вызывая сбой страницы, когда ядро ​​извлекает данные, к которым программа хочет получить доступ из файла с отображением памяти), тогда программа может выполнить еще несколько кода (вызывая исключение недопустимого кода операции, когда ядро ​​эмулирует более новую инструкцию, которая фактически не поддерживается на текущем / более старом ЦП), тогда программа может выполнить еще какой-то код (но будет прервана IRQ с сетевой карты, где ядро ​​/ устройство драйвер организует отправку / получение еще нескольких пакетов TCP / IP), тогда программа может выполнить еще какой-то код (но будет прервана таймером, который заставляет ядро ​​выполнять некоторые переключатели задач, чтобы другие процессы имели некоторое время ЦП), тогда программа может выполнить еще какой-то код (и будет прервана процессором, сообщающим ядру, что он становится горячим, когда ядро ​​может перенести процесс на другой более холодный процессор); и сама программа не будет знать, что что-то из этого произошло (и просто будет думать, что она все время использует процессор, хотя это не так).

...