Я написал LKM, который реализует Trusted Path Execution (TPE) в ваше ядро:
https://github.com/cormander/tpe-lkm
Я нахожусь в случайном ядре OOPS (описываю в конце этого вопроса), когда я определяю WRAP_SYSCALLS в 1, и я нахожусь в своем конце, пытаясь отследить его.
Немного фона:
Поскольку структура LSM не экспортирует свои символы, мне нужно было сделать креатив с тем, как я вставляю проверку TPE в запущенное ядро. Я написал функцию find_symbol_address(), которая дает мне адрес любой функции, которая мне нужна, и она работает очень хорошо. Я могу вызвать такие функции:
int (*my_printk)(const char *fmt, ...);
my_printk = find_symbol_address("printk");
(*my_printk)("Hello, world!\n");
И он отлично работает. Я использую этот метод для поиска функций security_file_mmap, security_file_mprotect и security_bprm_check.
Затем я перезаписываю эти функции с помощью asm-перехода к моей функции, чтобы выполнить проверку TPE. Проблема в том, что загруженный в настоящий момент LSM больше не будет выполнять код для привязки к этой функции, потому что он был полностью захвачен.
Вот пример того, что я делаю:
int tpe_security_bprm_check(struct linux_binprm *bprm) {
int ret = 0;
if (bprm->file) {
ret = tpe_allow_file(bprm->file);
if (IS_ERR(ret))
goto out;
}
#if WRAP_SYSCALLS
stop_my_code(&cs_security_bprm_check);
ret = cs_security_bprm_check.ptr(bprm);
start_my_code(&cs_security_bprm_check);
#endif
out:
return ret;
}
Обратите внимание на раздел раздела #if WRAP_SYSCALLS (по умолчанию он задан как 0). Если установлено значение 1, вызван LSM-крючок, потому что я пишу исходный код обратно через ASM-переход и вызываю эту функцию, но я запускаю случайное ядро OOPS с "недопустимым кодом операции":
invalid opcode: 0000 [#1] SMP
RIP: 0010:[<ffffffff8117b006>] [<ffffffff8117b006>] security_bprm_check+0x6/0x310
Я не знаю, в чем проблема. Я пробовал несколько разных типов методов блокировки (см. Внутреннюю часть start/stop_my_code для деталей) безрезультатно. Чтобы запустить ядро OOPS, напишите простой цикл bash while, который бесконечно запускает запрограммированную команду "ls". Через минуту или около того, это произойдет.
Я тестирую это на ядре RHEL6, также работает на Ubuntu 10.04 LTS (2.6.32 x86_64).
Пока этот метод был самым успешным до сих пор, я попробовал другой метод простого копирования функции ядра на указатель, созданный с помощью kmalloc, но когда я пытаюсь его выполнить, я получаю: Ядро попыталось выполнить NX-защищенную страницу - попытка использования? (uid: 0). Если кто-нибудь скажет мне, как это сделать в поле kmalloc и присвоить его как исполняемый файл, это также поможет мне решить указанную выше проблему.
Любая помощь приветствуется!