SELinux: Refactor state monitoring

Introduce a new API for SELinux state monitoring.
Move the API to a separate file.
This commit is contained in:
Mariusz Zaborski 2021-03-09 20:49:45 +01:00 committed by Adam 'pi3' Zabrocki
parent 7092d7aa0c
commit 59bed0a813
5 changed files with 95 additions and 69 deletions

View File

@ -86,6 +86,7 @@ $(TARGET)-objs += src/modules/ksyms/p_resolve_ksym.o \
src/modules/exploit_detection/syscalls/pCFI/p_lookup_fast/p_lookup_fast.o \
src/modules/exploit_detection/syscalls/p_capable/p_capable.o \
src/modules/exploit_detection/syscalls/p_scm_send/p_scm_send.o \
src/modules/exploit_detection/p_selinux_state.o \
src/modules/exploit_detection/p_exploit_detection.o \
src/p_lkrg_main.o

View File

@ -1684,12 +1684,11 @@ static void p_validate_selinux(void) {
#endif
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)
if (p_ed_guard_globals.p_selinux.p_selinux_state.enforcing != P_SYM(p_selinux_state)->enforcing) {
if (p_selinux_state_changed()) {
p_print_log(P_LKRG_CRIT,
"<Exploit Detection> Detected data corruption against SELINUX! 'selinux_state->enforcing' has "
"different value [%d vs %d] than expected!\n",
P_SYM(p_selinux_state)->enforcing,p_ed_guard_globals.p_selinux.p_selinux_state.enforcing);
p_selinux_state_enforcing(), p_ed_guard_globals.p_selinux.p_selinux_enforcing);
switch (P_CTRL(p_kint_enforce)) {
@ -1701,46 +1700,17 @@ static void p_validate_selinux(void) {
case 1:
p_print_log(P_LKRG_CRIT, "Original value will be restored!\n");
P_SYM(p_selinux_state)->enforcing = p_ed_guard_globals.p_selinux.p_selinux_state.enforcing;
p_selinux_state_restore();
break;
case 0:
p_print_log(P_LKRG_CRIT, "Accepting new state!\n");
p_ed_guard_globals.p_selinux.p_selinux_state.enforcing = P_SYM(p_selinux_state)->enforcing;
p_selinux_state_update();
break;
}
}
#else
if (p_ed_guard_globals.p_selinux.p_selinux_enforcing != *P_SYM(p_selinux_enforcing)) {
p_print_log(P_LKRG_CRIT,
"<Exploit Detection> Detected data corruption against SELINUX! 'selinux_enforcing' has "
"different value [%d vs %d] than expected. Original value will be restored!\n",
*P_SYM(p_selinux_enforcing),p_ed_guard_globals.p_selinux.p_selinux_enforcing);
switch (P_CTRL(p_kint_enforce)) {
/* Panic */
case 2:
// OK, we need to crash the kernel now
panic(P_LKRG_SIGNATURE "SELinux Integrity verification failed! Killing the kernel...\n");
break;
case 1:
p_print_log(P_LKRG_CRIT, "Original value will be restored!\n");
*P_SYM(p_selinux_enforcing) = p_ed_guard_globals.p_selinux.p_selinux_enforcing;
break;
case 0:
p_print_log(P_LKRG_CRIT, "Accepting new state!\n");
p_ed_guard_globals.p_selinux.p_selinux_enforcing = *P_SYM(p_selinux_enforcing);
break;
}
}
#endif
#endif
p_lkrg_counter_lock_unlock(&p_ed_guard_globals.p_selinux_lock, &p_flags);
}
@ -2285,27 +2255,6 @@ int p_exploit_detection_init(void) {
(defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8, 3))
P_SYM(p_selinux_enabled) = (int *)P_SYM(p_kallsyms_lookup_name)("selinux_enabled");
#endif
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)
P_SYM(p_selinux_state) = (struct p_selinux_state *)P_SYM(p_kallsyms_lookup_name)("selinux_state");
if (!P_SYM(p_selinux_state)) {
p_print_log(P_LKRG_ERR,
"[ED] ERROR: Can't find 'selinux_state' variable :( Exiting...\n");
p_ret = P_LKRG_GENERAL_ERROR;
goto p_exploit_detection_init_out;
}
#else
P_SYM(p_selinux_enforcing) = (int *)P_SYM(p_kallsyms_lookup_name)("selinux_enforcing");
if (!P_SYM(p_selinux_enforcing)) {
p_print_log(P_LKRG_ERR,
"[ED] ERROR: Can't find 'selinux_enforcing' variable :( Exiting...\n");
p_ret = P_LKRG_GENERAL_ERROR;
goto p_exploit_detection_init_out;
}
#endif
#endif
#if (!defined(RHEL_RELEASE_CODE) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)) || \
(defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8, 3))
@ -2331,11 +2280,12 @@ int p_exploit_detection_init(void) {
#ifdef CONFIG_SECURITY_SELINUX
// SELinux information
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)
p_ed_guard_globals.p_selinux.p_selinux_state.enforcing = P_SYM(p_selinux_state)->enforcing;
#else
p_ed_guard_globals.p_selinux.p_selinux_enforcing = *P_SYM(p_selinux_enforcing);
#endif
if (p_selinux_state_init()) {
p_print_log(P_LKRG_ERR,
"ERROR: Can't initialize selinux :(\n");
p_ret = P_LKRG_GENERAL_ERROR;
goto p_exploit_detection_init_out;
}
#endif
#if (!defined(RHEL_RELEASE_CODE) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)) || \
(defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8, 3))

View File

@ -282,11 +282,7 @@ struct p_ed_process_task {
struct p_ed_guard_selinux {
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)
struct p_selinux_state p_selinux_state;
#else
int p_selinux_enforcing;
#endif
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
int p_selinux_enabled;
@ -386,6 +382,12 @@ int p_ed_pcfi_validate_sp(struct task_struct *p_task, struct p_ed_process *p_ori
int p_exploit_detection_init(void);
void p_exploit_detection_exit(void);
int p_selinux_state_init(void);
void p_selinux_state_restore(void);
void p_selinux_state_update(void);
int p_selinux_state_changed(void);
int p_selinux_state_enforcing(void);
#ifdef P_LKRG_TASK_OFF_DEBUG
void p_debug_off_flag_off(struct p_ed_process *p_source, unsigned int p_id);
void p_debug_off_flag_on(struct p_ed_process *p_source, unsigned int p_id);

View File

@ -0,0 +1,77 @@
/*
* pi3's Linux kernel Runtime Guard
*
* Component:
* - selinux function
*
* Notes:
* - None
*
* Timeline:
* - Created: 17.III.2021
*
* Author:
* - Mariusz Zaborski (https://oshogbo.vexillium.org/)
*
*/
#include "../../p_lkrg_main.h"
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)
int p_selinux_state_init(void) {
P_SYM(p_selinux_state) = (struct p_selinux_state *)P_SYM(p_kallsyms_lookup_name)("selinux_state");
if (P_SYM(p_selinux_state) == NULL)
return P_LKRG_ERR;
return P_LKRG_SUCCESS;
}
void p_selinux_state_restore(void) {
P_SYM(p_selinux_state)->enforcing = p_ed_guard_globals.p_selinux.p_selinux_enforcing;
}
int p_selinux_state_enforcing(void) {
return P_SYM(p_selinux_state)->enforcing;
}
#else
int p_selinux_state_init(void) {
P_SYM(p_selinux_enforcing) = (int *)P_SYM(p_kallsyms_lookup_name)("selinux_enforcing");
if (P_SYM(p_selinux_enforcing) == NULL)
return P_LKRG_ERR;
p_selinux_state_update();
return P_LKRG_SUCCESS;
}
void p_selinux_restore(void) {
P_SYM(p_selinux_enforcing) = p_ed_guard_globals.p_selinux.p_selinux_enforcing;
}
int p_selinux_state_enforcing(void) {
return *P_SYM(p_selinux_enforcing);
}
#endif
void p_selinux_state_update(void) {
p_ed_guard_globals.p_selinux.p_selinux_enforcing = p_selinux_state_enforcing();
}
int p_selinux_state_changed(void) {
return p_selinux_state_enforcing() != p_ed_guard_globals.p_selinux.p_selinux_enforcing;
}
#endif

View File

@ -75,11 +75,7 @@ int p_sel_write_enforce_ret(struct kretprobe_instance *p_ri, struct pt_regs *p_r
if (!IS_ERR((void *)p_regs_get_ret(p_regs))) {
// track down new SELinux information
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)
p_ed_guard_globals.p_selinux.p_selinux_state.enforcing = P_SYM(p_selinux_state)->enforcing;
#else
p_ed_guard_globals.p_selinux.p_selinux_enforcing = *P_SYM(p_selinux_enforcing);
#endif
p_selinux_state_update();
#endif
#if (!defined(RHEL_RELEASE_CODE) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)) || \
(defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8, 3))