Я написал 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;
}
Обратите внимание на раздел между #, если 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 пробелом и пометить его как исполняемый, это также поможет мне решить вышеуказанную проблему.
Любая помощь приветствуется!