Как разместить исполняемую страницу в модуле ядра Linux?
Я пишу модуль ядра Linux, и я хотел бы выделить исполняемую страницу. Простой kmalloc возвращает указатель на неисполняемой странице, и я испытываю панику ядра, когда выполняю код там. Он должен работать на Ubuntu Karmic x86, 2.6.31-20-generic-pae.
3 ответа
#include <linux/vmalloc.h>
#include <asm/pgtype_types.h>
...
char *p = __vmalloc(byte_size, GFP_KERNEL, PAGE_KERNEL_EXEC);
...
if (p != NULL) vfree(p);
/**
* vmalloc_exec - allocate virtually contiguous, executable memory
* @size: allocation size
*
* Kernel-internal function to allocate enough pages to cover @size
* the page level allocator and map them into contiguous and
* executable kernel virtual space.
*
* For tight control over page level allocator and protection flags
* use __vmalloc() instead.
*
* Return: pointer to the allocated memory or %NULL on error
*/
void *vmalloc_exec(unsigned long size)
{
return __vmalloc_node(size, 1, GFP_KERNEL, PAGE_KERNEL_EXEC,
NUMA_NO_NODE, __builtin_return_address(0));
}
Linux 5.4 и более поздние версии больше не предоставляют интерфейсы, поэтому произвольные модули ядра не будут изменять атрибуты страницы для включения/выключения исполняемого бита. Однако может быть определенная конфигурация, которая позволит это сделать, но я о ней не знаю.
Если кто-то использует версию ядра ниже 5.4, вы можете использоватьset_memory_x(unsigned long addr, int numpages);
и друзья, чтобы изменить атрибуты страницы, или если вам нужно передатьstruct page
, вы могли бы использоватьset_pages_x
.
Имейте в виду, что это считается опасным, и вы должны знать, что делаете.