研究到 apparmor 内核源码,其中涉及到只读变量 __lsm_ro_after_init
,研究怎么修改只读区实现部分功能,这里记录一下。
思路上很简单,修改的时候禁用写保护,或者修改pte写保护属性。
实现上第一种更简单,所以采用第一种。
主要函数为 disable_write_protection
,修改cr0的写保护位即可。
inline void mywrite_cr0(unsigned long cr0) {
asm volatile("mov %0,%%cr0" : "+r"(cr0), "+m"(__force_order));
}
void enable_write_protection(void) {
unsigned long cr0 = read_cr0();
set_bit(16, &cr0);
mywrite_cr0(cr0);
}
void disable_write_protection(void) {
unsigned long cr0 = read_cr0();
clear_bit(16, &cr0);
mywrite_cr0(cr0);
}
static int hook_apparmor_func(void *arg)
{
union security_list_options *tmp = arg;
disable_write_protection();
tmp->file_permission = some_func;
enable_write_protection();
return 0;
}
static int recover_apparmor_func(void *arg)
{
union security_list_options *tmp = arg;
disable_write_protection();
tmp->file_permission = orig_apparmor_file_permission ;
enable_write_protection();
return 0;
}
void hook_apparmor(void)
{
struct security_hook_list *P;
struct hlist_head *head = &(orig_security_hook_heads->file_permission);
hlist_for_each_entry(P, head, list) {
if(strcmp(P->lsm, "apparmor") == 0){
orig_apparmor_file_permission = P->hook.file_permission;
stop_machine(hook_apparmor_func, (void*)&(P->hook), 0);
}
}
}
void recover_apparmor(void)
{
struct security_hook_list *P;
struct hlist_head *head = &(orig_security_hook_heads->file_permission);
hlist_for_each_entry(P, head, list) {
if(strcmp(P->lsm, "apparmor") == 0){
stop_machine(recover_apparmor_func, (void*)&(P->hook), 0);
}
}
}
Original: https://www.cnblogs.com/RayWHL/p/16263555.html
Author: RayWHL
Title: 修改内核中的只读区内容
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/607415/
转载文章受原作者版权保护。转载请注明原作者出处!