Для arm Linux могут ли потоки в пространстве пользователя получить доступ к виртуальному адресу пространства ядра?

Виртуальная память разделена на две части. Традиционно от 0 до 3 ГБ для пространства пользователя и от 3 до 4 ГБ для пространства ядра.

Мой вопрос:

Может ли поток в пространстве пользователя получить доступ к памяти пространства ядра?

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


person Haifeng Li    schedule 30.06.2012    source источник
comment
Я получил ответ. Управление разрешениями доступа по-прежнему зависит от домена и поля AP в записи таблицы страниц и регистре управления доступом к домену. До версии 2.6.38 код запуска инициализирует DOMAIN_USER с помощью DOMAIN_MANAGER. Но в Early_trap_init система изменит DOMAIN_USER на DOMAIN_CLIENT. И когда атрибут домена - DOMAIN_CLIENT, поле AP в записи таблицы страниц будет эффективным. Спасибо за следующие ответы.   -  person Haifeng Li    schedule 07.07.2012


Ответы (2)


Фактически, ваше приложение может получить доступ к странице 0xFFFF0000, поскольку она содержит swi-обработчик и несколько других помощников пользовательского пространства. Так что нет, в разделении 3/1 нет ничего волшебного, просто ядру очень легко управлять.

Обычно ядро ​​настраивает всю память размером более 3 ГБ, чтобы она была доступна только самому домену ядра. Если драйверу необходимо разделить память между пользователем и пространством ядра, он обычно предоставляет интерфейс mmap, который затем создает сопоставление с псевдонимом, поэтому у вас есть два виртуальных адреса для одного и того же физического адреса. Это надежно работает только в системах VIPT-Cache или с БОЛЬШОЙ тщательной явной очисткой кеша. Если вы этого не хотите, вы МОЖЕТЕ взломать ядро, чтобы сделать часть памяти НАД 3G-разделением доступной для пользовательского пространства. Но тогда все приложения пользовательского пространства будут совместно использовать эту память. Я проделал это однажды для специального приложения в системе armv5.

person Nico Erfurth    schedule 30.06.2012
comment
Спасибо за Ваш ответ. Я согласен. Вы говорите, что виртуальный адрес размером более 3 ГБ может быть доступен только самим доменом ядра и заблокирован доменом пользователя . Не могли бы вы вкратце рассказать, как это реализовать? - person Haifeng Li; 01.07.2012
comment
У меня есть ответ. Спасибо. - person Haifeng Li; 07.07.2012

Код пользовательского пространства получает память ядра? Единственное ядро, которое позволяло это делать, - это DOS и его архаичные друзья. Но вернемся к вопросу, посмотрим на этот пример кода C:

char c=42;
*c=42;

Мы берем один байт (a char) и присваиваем ему числовое значение 42. Затем мы разыменовываем этот не-указатель, который, вероятно, попытается получить доступ к 42-му байту виртуальной памяти, который почти определенно не ваш память и, в данном примере, память ядра. угадайте, что произойдет, когда вы запустите это (если вам удастся держать компилятор под дулом пистолета):

Segmentation fault

Linux имеет защиту памяти, как и любая современная операционная система. Если вы попытаетесь получить доступ к памяти другого процесса, ваш процесс будет остановлен, прежде чем он сможет что-либо сделать (хотя я не уверен в том, что с отладчиками произойдут другие вещи). Даже если бы эта память была памятью другого процесса Userland, вы все равно были бы остановлены. Я почти уверен, что root программы не могут получить доступ к памяти других программ или памяти ядра. Единственный способ получить доступ к памяти ядра - быть частью ядра или косвенно через взаимодействие с ядром.

person Linuxios    schedule 30.06.2012
comment
Пользовательское пространство с достаточными привилегиями может открываться /dev/kmem в Linux (если оно настроено), которое является виртуальной памятью ядра ;-) - person ephemient; 30.06.2012
comment
@ephemient: Правда? Но достаточно привилегированный еще не означает, что он доступен для записи, верно? Или достаточно привилегий просто работает как root? - person Linuxios; 30.06.2012
comment
Если ядро ​​настроено с CONFIG_DEVKMEM=y и нет LSM (таких как SELinux), блокирующих доступ, наличие CAP_SYS_RAWIO (root имеет все возможности, и они могут быть предоставлены другим процессам) достаточно для чтения и записи /dev/kmem. Когда-то так работала загрузка модулей, но теперь это уже не так. - person ephemient; 01.07.2012
comment
@ephemient: Правда? Странно. Но если вы запускаете инструмент для тестирования с root доступом, пытаясь проникнуть в ядро, вы, вероятно, делаете что-то не так. - person Linuxios; 01.07.2012
comment
Существуют также API-интерфейсы, которые разделяют пользовательскую память и память пространства ядра, например пакет-mmap, они обычно переводят пространство ядра mmap в пространство пользователя, используя один и тот же физический адрес, но разные виртуальные адреса. В настоящее время НЕТ интерфейса ядра, который позволяет использовать один и тот же физический И виртуальный адрес. Но вы МОЖЕТЕ (и я уже сделал) создать память ядра, доступную для всех процессов пользовательского пространства. Это очень хакерский и специфичный для архитектуры подход, но он был необходим для специального приложения (совместного использования памяти без проблем с псевдонимом, вводимых VIVT-DCache) в ограниченной среде. - person Nico Erfurth; 07.07.2012