This source file includes following definitions.
- sort_main_extable
- search_kernel_exception_table
- search_exception_tables
- init_kernel_text
- core_kernel_text
- core_kernel_data
- __kernel_text_address
- kernel_text_address
- func_ptr_is_kernel_text
1
2
3
4
5
6 #include <linux/ftrace.h>
7 #include <linux/memory.h>
8 #include <linux/extable.h>
9 #include <linux/module.h>
10 #include <linux/mutex.h>
11 #include <linux/init.h>
12 #include <linux/kprobes.h>
13 #include <linux/filter.h>
14
15 #include <asm/sections.h>
16 #include <linux/uaccess.h>
17
18
19
20
21
22
23
24
25
26 DEFINE_MUTEX(text_mutex);
27
28 extern struct exception_table_entry __start___ex_table[];
29 extern struct exception_table_entry __stop___ex_table[];
30
31
32 u32 __initdata __visible main_extable_sort_needed = 1;
33
34
35 void __init sort_main_extable(void)
36 {
37 if (main_extable_sort_needed && __stop___ex_table > __start___ex_table) {
38 pr_notice("Sorting __ex_table...\n");
39 sort_extable(__start___ex_table, __stop___ex_table);
40 }
41 }
42
43
44 const
45 struct exception_table_entry *search_kernel_exception_table(unsigned long addr)
46 {
47 return search_extable(__start___ex_table,
48 __stop___ex_table - __start___ex_table, addr);
49 }
50
51
52 const struct exception_table_entry *search_exception_tables(unsigned long addr)
53 {
54 const struct exception_table_entry *e;
55
56 e = search_kernel_exception_table(addr);
57 if (!e)
58 e = search_module_extables(addr);
59 return e;
60 }
61
62 int init_kernel_text(unsigned long addr)
63 {
64 if (addr >= (unsigned long)_sinittext &&
65 addr < (unsigned long)_einittext)
66 return 1;
67 return 0;
68 }
69
70 int notrace core_kernel_text(unsigned long addr)
71 {
72 if (addr >= (unsigned long)_stext &&
73 addr < (unsigned long)_etext)
74 return 1;
75
76 if (system_state < SYSTEM_RUNNING &&
77 init_kernel_text(addr))
78 return 1;
79 return 0;
80 }
81
82
83
84
85
86
87
88
89
90
91
92 int core_kernel_data(unsigned long addr)
93 {
94 if (addr >= (unsigned long)_sdata &&
95 addr < (unsigned long)_edata)
96 return 1;
97 return 0;
98 }
99
100 int __kernel_text_address(unsigned long addr)
101 {
102 if (kernel_text_address(addr))
103 return 1;
104
105
106
107
108
109
110
111
112 if (init_kernel_text(addr))
113 return 1;
114 return 0;
115 }
116
117 int kernel_text_address(unsigned long addr)
118 {
119 bool no_rcu;
120 int ret = 1;
121
122 if (core_kernel_text(addr))
123 return 1;
124
125
126
127
128
129
130
131
132
133
134
135 no_rcu = !rcu_is_watching();
136
137
138 if (no_rcu)
139 rcu_nmi_enter();
140
141 if (is_module_text_address(addr))
142 goto out;
143 if (is_ftrace_trampoline(addr))
144 goto out;
145 if (is_kprobe_optinsn_slot(addr) || is_kprobe_insn_slot(addr))
146 goto out;
147 if (is_bpf_text_address(addr))
148 goto out;
149 ret = 0;
150 out:
151 if (no_rcu)
152 rcu_nmi_exit();
153
154 return ret;
155 }
156
157
158
159
160
161
162
163
164 int func_ptr_is_kernel_text(void *ptr)
165 {
166 unsigned long addr;
167 addr = (unsigned long) dereference_function_descriptor(ptr);
168 if (core_kernel_text(addr))
169 return 1;
170 return is_module_text_address(addr);
171 }