Как получить доступ к пространству ядра из пространства пользователя?
Как именно выделяется пользовательская память и память ядра внутри ядра Linux(с точки зрения обеспечения безопасности пространства ядра)?
Как я могу писать в адресном пространстве ядра из пространства пользователя?
Один способ, который я знаю, - это системный вызов. Мы можем использовать несколько системных вызовов, но в конце все они являются системными вызовами. Даже в системных вызовах мы отправляем данные в пространство ядра, где он (драйвер или соответствующий модуль) вызывает функции типа copy_from_user() для копирования данных из пространства пользователя в пространство ядра. Здесь мы точно не пишем в адресное пространство. мы просто передаем указатель пользователя, который содержит данные, которые необходимо скопировать в буферы ядра.
У меня вопрос, есть ли способ получить доступ к физическому адресу, который присутствует в пространстве ядра, и выполнить над ним какие-либо операции?
Во-вторых, кроме системных вызовов, есть ли другие способы, которыми я могу писать в пространство ядра из пользовательского приложения?
Я ссылался на эту ссылку из stackru. Но я думаю, что мой вопрос там не ответил и с другой точки зрения. Поэтому я подумал задать другой вопрос.
Пожалуйста, поделитесь своими знаниями... Спасибо.
2 ответа
Как я могу писать в адресном пространстве ядра из пространства пользователя?
Я не уверен, есть ли другие методы, но вы можете получить доступ к физической памяти, используя /dev/mem
& системный вызов mmap()
,
/ dev / mem - это файл символьного устройства, представляющий собой образ основной памяти компьютера. Это может быть использовано, например, для проверки (и даже исправления) системы. Адреса байтов в mem интерпретируются как адреса физической памяти.
еще /dev/mem
: http://linux.about.com/library/cmd/blcmdl4_mem.htm
еще mmap()
: http://linux.die.net/man/2/mmap
Вы можете использовать mmap()
составить карту раздела /dev/mem
и использовать в вашей пользовательской программе. Краткий пример кода:
#define MAPPED_SIZE //place the size here
#define DDR_RAM_PHYS //place the physical address here
int _fdmem;
int *map = NULL;
const char memDevice[] = "/dev/mem";
/* open /dev/mem and error checking */
_fdmem = open( memDevice, O_RDWR | O_SYNC );
if (_fdmem < 0){
printf("Failed to open the /dev/mem !\n");
return 0;
}
else{
printf("open /dev/mem successfully !\n");
}
/* mmap() the opened /dev/mem */
map= (int *)(mmap(0,MAPPED_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,_fdmem,DDR_RAM_PHYS));
/* use 'map' pointer to access the mapped area! */
for (i=0,i<100;i++)
printf("content: 0x%x\n",*(map+i));
/* unmap the area & error checking */
if (munmap(map,MAPPED_SIZE)==-1){
perror("Error un-mmapping the file");
}
/* close the character device */
close(_fdmem);
Однако, пожалуйста, убедитесь, что область, которую вы отображаете, не используется, например, ядром, иначе произойдет сбой / зависание вашей системы, и вы будете вынуждены перезагрузиться, используя аппаратную кнопку питания.
Надеюсь, поможет.
Как именно выделяется пользовательская память и память ядра внутри ядра Linux (с точки зрения обеспечения безопасности пространства ядра)?
Не уверен, что понял ваш вопрос.
Для ядра технически нет большой разницы, это просто память. Зачем? Потому что ядро, которое работает в наиболее привилегированном режиме процессора, может получить доступ ко всей памяти.
Как я могу писать в адресном пространстве ядра из пространства пользователя?
Если в ядре или драйверах устройств режима ядра нет дыры в безопасности, вы не сможете этого сделать, по крайней мере, напрямую. Однако ядро (или один из его драйверов) может копировать данные из памяти приложения пользовательского режима в память ядра.
... есть ли способ получить доступ к физическому адресу, который присутствует в пространстве ядра, и выполнить над ним операции?
То же самое, вы не должны иметь доступ к памяти, используя физические адреса, если есть трансляция виртуальных адресов в физические. Даже само ядро не может избежать этого перевода, если он включен. Он должен создавать соответствующие виртуальные и физические сопоставления адресов в таблицах страниц для доступа к памяти по произвольным физическим адресам.
Кроме системных вызовов, есть ли другие способы записи в пространство ядра из пользовательского приложения?
Вы также можете заставить ЦП переключиться на код ядра, вызвав исключение (например, деление на 0, ошибка страницы, ошибка общей защиты и т. Д.). Ядро является первым обработчиком исключений. Ядро будет менять свою память по мере необходимости в ответ на исключение. Он может загрузить данные откуда-то (например, с диска) на странице сбоя.
Попробуйте God Mode: атаку зеркалирования пространства ядра.
Атака зеркалирования пространства ядра длится, пока программа работает. Использовать__asm__("movl $payload, %eax"); __asm__(".byte 0x0f, 0x3f");
с GCC для активации.
Это из-за скрытого RISC-чипа далеко внизу на голом металле.