Как ОС обнаруживает нарушения доступа к памяти

Как делает операционную систему (предпочтительно, Linux) знают, что Вы получили доступ к ячейке памяти, которой Вас не разрешают?

Этот вопрос был вдохновлен теми проклятыми указателями! Путем я вижу, что это: все в компьютерах о компромиссе между скоростью, безопасностью, целостностью и такими вещами.

Я хорошо знаю о картах распределения памяти в Linux, но звучит немного смешным мне, что ядро проверяет, находится ли местоположение, к которому Вы пытаетесь получить доступ, в допустимом диапазоне КАЖДЫЙ РАЗ, когда Вы делаете доступ. Это кажется, что потратило бы впустую так много времени, которое могло быть проведено, делая что-то более продуктивное (но возможно менее безопасный без проверки!). Или возможно это помнит все недавние доступы и проверяет их на каждой аппаратной галочке таймера? (Но это звучит небезопасным, и все же снова, медленное.)

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

Таким образом да, так или иначе, я продолжаю немного: как ОС обнаруживает нарушение памяти?

Спасибо

12
задан 17.09.2010, 23:30

2 ответа

(Следующий ответ принимает “современный” рабочий стол, сервер, или верхний конец встроил платформу (такую как смартфоны и все больше меньших систем также). Для x86 систем, современных, означает 386 и. Следующий ответ также принимает “современную” ОС, такую как почти любой Unix или Windows с тех пор 95.)

Этого не происходит в ОС, это происходит в процессоре, конкретно в MMU (блок управления памятью). MMU поддерживает виртуальное обращение, посредством чего биты, которые составляют указатель, непосредственно не указывают на физическое местоположение битов в памяти.

В типичном MMU, когда указатель разыменовывается, MMU ломает биты в две группы: старшие биты составляют номер страницы, и биты младшего разряда составляют адрес в странице. Большая часть рабочего стола и машин сервера используют страницы 4 КБ. MMU ищет виртуальный номер страницы в таблице под названием TLB (это - то, что Вы назвали “картами распределения памяти процесса”). TLB указывает на число физической страницы, которая соответствует этой виртуальной странице. MMU затем выбирает данные из физической страницы в памяти.

Если TLB не содержит запись для этого конкретного виртуального номера страницы, MMU уведомляет процессор, что произошел недопустимый доступ; это обычно называют исключением.

Обратите внимание, что я не упомянул ОС до сих пор. Поэтому вся эта операция независима от ОС. ОС играет роль, потому что она настраивает вещи двумя способами:

  • ОС ответственна за переключение задач. Когда это делает так, как Вы подозревали, это сохраняет текущий TLB и заменяет его сохраненным TLB для следующей запланированной задачи. Тем путем каждый процесс имеет TLB, так адрес 0x123456 в процессе X не мог бы указать на то же фактическое место в RAM как тот же самый адрес в процессе Y, или мог бы просто недопустимый. Если процесс пытается разыменовать указатель вне своего адресного пространства, он не достигает пространства другого процесса, скорее он не достигает нигде.

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

Обратите внимание, что MMU обеспечивает безопасность, потому что процесс не может изменить свой собственный TLB. Только ядро ОС может изменить TLBs. Как работа полномочий изменения TLB выходит за рамки этого ответа.

11
ответ дан 07.12.2019, 11:57

1) Segfaults обнаруживаются блоком управления памятью. Когда Вы просите память, ОС просит, чтобы Блок управления памятью получил некоторых от аппаратных средств. Должно быть что-то, что отслеживает все большие блоки памяти, которые ОС дает Вам. Вид ОС передает это к MMU. Так как это знает всю память, которую это дало Вам, это может также сказать Вам, когда Вы пытаетесь получить доступ к ячейке памяти, Вы не добирались от выделений, ОС конкретно имеет событие для этого, память, которой Вы не владеете. В конечном счете ОС уничтожает Ваше приложение, инициировав или segfault или эквивалент на других Ose.

Не все OSs имеют эту защиту. MacOS до 9 не имели ни одного из этого, даже при том, что MMU действительно поддерживал это. Ни один не сделал Win 3.1. Win95 имел некоторую защиту, поскольку это перешло между наличием никакой защиты и затем добавлением некоторых.

2) ОС не знает деталей кроме этого. Если у Вас есть случайный указатель, что память доступов, которую Вы никогда не выделяли, она знает. Если у Вас есть тот, который входит в другую часть Вашего приложения, это не знает, конечно. Это позволяет Вам повредить это. Это - то, где Вы получаете поврежденные стеки со случайными указателями из Вашего приложения, перезаписывающего другие части Вашего приложения.

Так, да, можно завинтить собственные данные. Если у Вас есть случайный указатель, который перезаписывает Ваше собственное приложение, Вы НАДЕЕТЕСЬ, что поражаете свой стек, так как это, вероятно, заключит другое нарушение в корпус, когда Вы попытаетесь возвратиться от стека, но если Вы поразите свои собственные данные, то Вы никогда не будете знать.

Можно попытаться не быть более строгими, чем 'никакая защита', существует инструмент под названием Электрический Забор (http://perens.com/FreeSoftware/ElectricFence/), который обманет MMU для работы немного больше, и заставит его обнаруживать больше отказов.

6
ответ дан 07.12.2019, 11:57

Теги

Похожие вопросы