-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathald.c
143 lines (120 loc) · 4.15 KB
/
ald.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include <linux/module.h>
#include <linux/audit.h>
#include <linux/sched.h>
#include <linux/version.h>
#include <linux/kprobes.h>
#include <linux/moduleparam.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
#define KERNEL_HAS_CET
#endif
#if defined(CONFIG_X86) && defined(KERNEL_HAS_CET)
#include <asm/msr.h>
#endif
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Alessandro Carminati");
#define DEBUG
#ifndef DODEBUG
#ifdef DEBUG
#define DODEBUG(fmt, ... ) printk(fmt, ##__VA_ARGS__ );
#else
#define DODEBUG(fmt, ... ) do { } while(0)
#endif
#endif
static unsigned long kernel_locked_down_addr = 0;
module_param(kernel_locked_down_addr, ulong, 0);
MODULE_PARM_DESC(kernel_locked_down_addr," kernel_locked_down_addr: Address where the kernel_locked_down symbol points to.");
#define KSYM_NAME_PLUS_OFFSETS ( KSYM_NAME_LEN + 1 + 19 + 1 + 19 )
static char symname[KSYM_NAME_PLUS_OFFSETS];
static char targetSymname[] = "kernel_locked_down+0x0/0x4\0";
typedef unsigned long (*kallsyms_lookup_name_t)(const char *name);
int pre(struct kprobe *p, struct pt_regs *regs){
return 0;
}
static void post(struct kprobe *p, struct pt_regs *regs, unsigned long flags) {
}
/* int fault(struct kprobe *p, struct pt_regs *regs, int trapnr){ */
/* return 0; */
/* } */
static struct kprobe k = {
.symbol_name = "kallsyms_lookup_name",
.pre_handler = pre,
.post_handler = post
// .fault_handler = fault
};
static kallsyms_lookup_name_t get_kallsyms_lookup_name_addr(void){
kallsyms_lookup_name_t ret;
int dbg;
DODEBUG(KERN_INFO "ald - get_kallsyms_lookup_name_addr");
if ( (dbg=register_kprobe(&k)) < 0) {
DODEBUG(KERN_INFO "ald - register_kprobe error %d\n", dbg);
return NULL;
}
DODEBUG(KERN_INFO "ald - probe registered\n");
ret = (kallsyms_lookup_name_t) k.addr;
DODEBUG(KERN_INFO "ald - kallsyms_lookup_name is at %px\n", ret);
unregister_kprobe(&k);
return ret;
}
static int init(void){
kallsyms_lookup_name_t kallsyms_lookup_name;
int *kld;
#if defined(CONFIG_X86) && defined(KERNEL_HAS_CET)
unsigned long long save_msr;
unsigned long long new_msr;
#endif
int symname_len;
kld = 0;
if ( kernel_locked_down_addr ) {
DODEBUG(KERN_INFO "ald - Parameter kernel_locked_down_addr is %lx", kernel_locked_down_addr);
symname_len = sprint_symbol(symname, kernel_locked_down_addr);
} else {
DODEBUG(KERN_INFO "ald - Paramater kernel_locked_down_addr is 0 or not given.")
}
if ( kernel_locked_down_addr && ( strncmp(symname, targetSymname, symname_len) == 0 ) ) {
DODEBUG(KERN_INFO "ald - The symbol of the address from the parameter actually matches %s.",
targetSymname);
kld = (int *) (kernel_locked_down_addr);
} else {
kernel_locked_down_addr = 0;
DODEBUG(KERN_INFO "ald - The parameter kernel_locked_down_addr was not given or does not match %s. So ignoring paramter input.",
targetSymname);
kallsyms_lookup_name=get_kallsyms_lookup_name_addr();
if (kallsyms_lookup_name) {
#if defined(CONFIG_X86) && defined(KERNEL_HAS_CET)
if (cpu_feature_enabled(X86_FEATURE_IBT)) {
rdmsrl(MSR_IA32_S_CET, save_msr);
if ( (save_msr & CET_ENDBR_EN) ) {
DODEBUG(KERN_INFO "ald - IBT is enabled");
new_msr = save_msr & (~ CET_ENDBR_EN);
wrmsrl(MSR_IA32_S_CET, new_msr);
DODEBUG(KERN_INFO "ald - IBT temporarily disabled");
};
} else {
DODEBUG(KERN_INFO "ald - IBT is not supported by CPU. So nothing to bother.")
};
#endif
kld = (int *) (*kallsyms_lookup_name)("kernel_locked_down");
DODEBUG(KERN_INFO "ald - kernel_locked_down from kallsyms_lookup_name at %px", kld);
#if defined(CONFIG_X86) && defined(KERNEL_HAS_CET)
if ( cpu_feature_enabled(X86_FEATURE_IBT) && (save_msr & CET_ENDBR_EN) ) {
wrmsrl(MSR_IA32_S_CET, save_msr);
DODEBUG(KERN_INFO "ald - IBT restored");
};
#endif
} else {
pr_info("ald - can't get kallsyms_lookup_name addr\n");
}
};
if (kld) {
*kld = 0;
printk(KERN_INFO "ald - Module ready. Lockdown level reset.\n");
} else {
pr_info("ald - not supported for this kernel or kernel_locked_down could not be located.\n");
}
return 0;
}
static void cleanup(void){
printk(KERN_INFO "ald - Module removed.\n");
}
module_init(init);
module_exit(cleanup);