Как разместить исполняемую страницу в модуле ядра 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.

Имейте в виду, что это считается опасным, и вы должны знать, что делаете.

Другие вопросы по тегам