|
14 | 14 | #include <asm/stacktrace.h>
|
15 | 15 | #include <net/tcp.h>
|
16 | 16 |
|
17 |
| -#include "inl_hook.h" |
| 17 | +#include "util.h" |
18 | 18 |
|
19 | 19 |
|
20 |
| -struct instr_range { |
21 |
| - unsigned long start; |
22 |
| - unsigned long end; |
23 |
| -}; |
| 20 | +/* variable */ |
| 21 | +static void (*tcp_set_state_fn)(struct sock *sk, int state); |
| 22 | + |
| 23 | +/* hook function */ |
| 24 | +static void my_tcp_set_state(struct sock *sk, int state); |
24 | 25 |
|
25 | 26 |
|
26 |
| -#define MAX_STACK_TRACE_DEPTH 64 |
27 |
| -static unsigned long stack_entries[MAX_STACK_TRACE_DEPTH]; |
28 |
| -struct stack_trace trace = { |
29 |
| - .max_entries = ARRAY_SIZE(stack_entries), |
30 |
| - .entries = &stack_entries[0], |
| 27 | +static struct symbol_ops hello_ops[] = { |
| 28 | + DECLARE_SYMBOL(&tcp_set_state_fn, "tcp_set_state"), |
31 | 29 | };
|
32 | 30 |
|
33 | 31 |
|
34 |
| -/* variable */ |
35 |
| -static void (*tcp_set_state_fn)(struct sock *sk, int state); |
| 32 | +static struct hook_ops hello_hooks[] = { |
| 33 | + DECLARE_HOOK(&tcp_set_state_fn, my_tcp_set_state), |
| 34 | +}; |
36 | 35 |
|
37 | 36 |
|
38 | 37 | /* hook function */
|
@@ -90,130 +89,27 @@ my_tcp_set_state(struct sock *sk, int state)
|
90 | 89 | }
|
91 | 90 |
|
92 | 91 |
|
93 |
| -static int |
94 |
| -init_find_ksymbol(void) |
95 |
| -{ |
96 |
| - tcp_set_state_fn = (void *) kallsyms_lookup_name("tcp_set_state"); |
97 |
| - if (tcp_set_state_fn == NULL) { |
98 |
| - pr_err("not find tcp_set_state.\n"); |
99 |
| - return -1; |
100 |
| - } |
101 |
| - |
102 |
| - return 0; |
103 |
| -} |
104 |
| - |
105 |
| - |
106 |
| -/* Called from stop_machine */ |
107 |
| -static int |
108 |
| -hello_safe_unhook_all(void *data) |
109 |
| -{ |
110 |
| - struct task_struct *g, *t; |
111 |
| - int i; |
112 |
| - int ret = 0; |
113 |
| - unsigned long address; |
114 |
| - struct instr_range irs[2] = { |
115 |
| - { |
116 |
| - .start = ((struct instr_range *)data)->start, |
117 |
| - .end = ((struct instr_range *)data)->end, |
118 |
| - }, |
119 |
| - { |
120 |
| - .start = (unsigned long)hello_safe_unhook_all, |
121 |
| - .end = (unsigned long)&&lable_unhook_end, |
122 |
| - } |
123 |
| - }; |
124 |
| - |
125 |
| - /* Check the stacks of all tasks. */ |
126 |
| - do_each_thread(g, t) { |
127 |
| - trace.nr_entries = 0; |
128 |
| - save_stack_trace_tsk(t, &trace); |
129 |
| - |
130 |
| - if (trace.nr_entries >= trace.max_entries) { |
131 |
| - ret = -EBUSY; |
132 |
| - pr_err("more than %u trace entries!\n", |
133 |
| - trace.max_entries); |
134 |
| - goto out; |
135 |
| - } |
136 |
| - |
137 |
| - for (i = 0; i < trace.nr_entries; i++) { |
138 |
| - if (trace.entries[i] == ULONG_MAX) |
139 |
| - break; |
140 |
| - |
141 |
| - address = trace.entries[i]; |
142 |
| - |
143 |
| - // without cleanup function. |
144 |
| - if ((address >= irs[0].start && address < irs[0].end) |
145 |
| - || (address >= irs[1].start && address < irs[1].end)) { |
146 |
| - break; |
147 |
| - } |
148 |
| - |
149 |
| - ret = inl_within_trampoline(address); |
150 |
| - if (ret) |
151 |
| - goto out; |
152 |
| - |
153 |
| - if (within_module_core(address, THIS_MODULE)) { |
154 |
| - pr_info("within: %lx\n", trace.entries[i]); |
155 |
| - ret = -EBUSY; |
156 |
| - goto out; |
157 |
| - } |
158 |
| - } |
159 |
| - } while_each_thread(g, t); |
160 |
| - |
161 |
| - // hook cleanup. |
162 |
| - inl_unhook(my_tcp_set_state); |
163 |
| - |
164 |
| -out: |
165 |
| - return ret; |
166 |
| - |
167 |
| -lable_unhook_end: |
168 |
| - ; |
169 |
| -} |
170 |
| - |
171 |
| - |
172 | 92 | static int __init hello_init(void)
|
173 | 93 | {
|
174 |
| - int ret; |
175 |
| - |
176 |
| - ret = init_find_ksymbol(); |
177 |
| - if (ret < 0) { |
178 |
| - pr_err("find ksymbol fail.\n"); |
179 |
| - goto exit; |
| 94 | + if (!find_ksymbol(hello_ops, ARRAY_SIZE(hello_ops))) { |
| 95 | + pr_err("hello symbol table not find.\n"); |
| 96 | + return -1; |
180 | 97 | }
|
181 | 98 |
|
182 |
| - ret = inl_sethook((void **)&tcp_set_state_fn, my_tcp_set_state); |
183 |
| - if (ret < 0) { |
184 |
| - pr_err("inl_sethook tcp_set_state fail.\n"); |
185 |
| - goto exit; |
| 99 | + if (!inl_sethook_ops(hello_hooks, ARRAY_SIZE(hello_hooks))) { |
| 100 | + pr_err("hijack hello functions fail.\n"); |
| 101 | + return -1; |
186 | 102 | }
|
187 | 103 |
|
188 | 104 | pr_info("hello loaded.\n");
|
189 |
| - |
190 | 105 | return 0;
|
191 |
| - |
192 |
| -exit: |
193 |
| - return ret; |
194 | 106 | }
|
195 | 107 |
|
196 | 108 |
|
197 | 109 | static void __exit hello_cleanup(void)
|
198 | 110 | {
|
199 |
| - int ret; |
200 |
| - struct instr_range ir; |
201 |
| - |
202 |
| -try_again_unhook: |
203 |
| - ir.start = (unsigned long)hello_cleanup; |
204 |
| - ir.end = (unsigned long)&&lable_cleanup_end; |
205 |
| - |
206 |
| - ret = stop_machine(hello_safe_unhook_all, &ir, NULL); |
207 |
| - if (ret) { |
208 |
| - yield(); |
209 |
| - pr_info("module busy, retry again unhook.\n"); |
210 |
| - goto try_again_unhook; |
211 |
| - } |
212 |
| - |
| 111 | + inl_unhook_ops(hello_hooks, ARRAY_SIZE(hello_hooks)); |
213 | 112 | pr_info("hello unloaded.\n");
|
214 |
| - |
215 |
| -lable_cleanup_end: |
216 |
| - ; |
217 | 113 | }
|
218 | 114 |
|
219 | 115 |
|
|
0 commit comments