diff options
Diffstat (limited to 'kernel/kprobes.c')
-rw-r--r-- | kernel/kprobes.c | 163 |
1 files changed, 0 insertions, 163 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index b4aab48ad258..da2ccf142358 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
@@ -83,16 +83,6 @@ static raw_spinlock_t *kretprobe_table_lock_ptr(unsigned long hash) | |||
83 | return &(kretprobe_table_locks[hash].lock); | 83 | return &(kretprobe_table_locks[hash].lock); |
84 | } | 84 | } |
85 | 85 | ||
86 | /* List of symbols that can be overriden for error injection. */ | ||
87 | static LIST_HEAD(kprobe_error_injection_list); | ||
88 | static DEFINE_MUTEX(kprobe_ei_mutex); | ||
89 | struct kprobe_ei_entry { | ||
90 | struct list_head list; | ||
91 | unsigned long start_addr; | ||
92 | unsigned long end_addr; | ||
93 | void *priv; | ||
94 | }; | ||
95 | |||
96 | /* Blacklist -- list of struct kprobe_blacklist_entry */ | 86 | /* Blacklist -- list of struct kprobe_blacklist_entry */ |
97 | static LIST_HEAD(kprobe_blacklist); | 87 | static LIST_HEAD(kprobe_blacklist); |
98 | 88 | ||
@@ -1404,17 +1394,6 @@ bool within_kprobe_blacklist(unsigned long addr) | |||
1404 | return false; | 1394 | return false; |
1405 | } | 1395 | } |
1406 | 1396 | ||
1407 | bool within_kprobe_error_injection_list(unsigned long addr) | ||
1408 | { | ||
1409 | struct kprobe_ei_entry *ent; | ||
1410 | |||
1411 | list_for_each_entry(ent, &kprobe_error_injection_list, list) { | ||
1412 | if (addr >= ent->start_addr && addr < ent->end_addr) | ||
1413 | return true; | ||
1414 | } | ||
1415 | return false; | ||
1416 | } | ||
1417 | |||
1418 | /* | 1397 | /* |
1419 | * If we have a symbol_name argument, look it up and add the offset field | 1398 | * If we have a symbol_name argument, look it up and add the offset field |
1420 | * to it. This way, we can specify a relative address to a symbol. | 1399 | * to it. This way, we can specify a relative address to a symbol. |
@@ -2189,86 +2168,6 @@ static int __init populate_kprobe_blacklist(unsigned long *start, | |||
2189 | return 0; | 2168 | return 0; |
2190 | } | 2169 | } |
2191 | 2170 | ||
2192 | #ifdef CONFIG_BPF_KPROBE_OVERRIDE | ||
2193 | /* Markers of the _kprobe_error_inject_list section */ | ||
2194 | extern unsigned long __start_kprobe_error_inject_list[]; | ||
2195 | extern unsigned long __stop_kprobe_error_inject_list[]; | ||
2196 | |||
2197 | /* | ||
2198 | * Lookup and populate the kprobe_error_injection_list. | ||
2199 | * | ||
2200 | * For safety reasons we only allow certain functions to be overriden with | ||
2201 | * bpf_error_injection, so we need to populate the list of the symbols that have | ||
2202 | * been marked as safe for overriding. | ||
2203 | */ | ||
2204 | static void populate_kprobe_error_injection_list(unsigned long *start, | ||
2205 | unsigned long *end, | ||
2206 | void *priv) | ||
2207 | { | ||
2208 | unsigned long *iter; | ||
2209 | struct kprobe_ei_entry *ent; | ||
2210 | unsigned long entry, offset = 0, size = 0; | ||
2211 | |||
2212 | mutex_lock(&kprobe_ei_mutex); | ||
2213 | for (iter = start; iter < end; iter++) { | ||
2214 | entry = arch_deref_entry_point((void *)*iter); | ||
2215 | |||
2216 | if (!kernel_text_address(entry) || | ||
2217 | !kallsyms_lookup_size_offset(entry, &size, &offset)) { | ||
2218 | pr_err("Failed to find error inject entry at %p\n", | ||
2219 | (void *)entry); | ||
2220 | continue; | ||
2221 | } | ||
2222 | |||
2223 | ent = kmalloc(sizeof(*ent), GFP_KERNEL); | ||
2224 | if (!ent) | ||
2225 | break; | ||
2226 | ent->start_addr = entry; | ||
2227 | ent->end_addr = entry + size; | ||
2228 | ent->priv = priv; | ||
2229 | INIT_LIST_HEAD(&ent->list); | ||
2230 | list_add_tail(&ent->list, &kprobe_error_injection_list); | ||
2231 | } | ||
2232 | mutex_unlock(&kprobe_ei_mutex); | ||
2233 | } | ||
2234 | |||
2235 | static void __init populate_kernel_kprobe_ei_list(void) | ||
2236 | { | ||
2237 | populate_kprobe_error_injection_list(__start_kprobe_error_inject_list, | ||
2238 | __stop_kprobe_error_inject_list, | ||
2239 | NULL); | ||
2240 | } | ||
2241 | |||
2242 | static void module_load_kprobe_ei_list(struct module *mod) | ||
2243 | { | ||
2244 | if (!mod->num_kprobe_ei_funcs) | ||
2245 | return; | ||
2246 | populate_kprobe_error_injection_list(mod->kprobe_ei_funcs, | ||
2247 | mod->kprobe_ei_funcs + | ||
2248 | mod->num_kprobe_ei_funcs, mod); | ||
2249 | } | ||
2250 | |||
2251 | static void module_unload_kprobe_ei_list(struct module *mod) | ||
2252 | { | ||
2253 | struct kprobe_ei_entry *ent, *n; | ||
2254 | if (!mod->num_kprobe_ei_funcs) | ||
2255 | return; | ||
2256 | |||
2257 | mutex_lock(&kprobe_ei_mutex); | ||
2258 | list_for_each_entry_safe(ent, n, &kprobe_error_injection_list, list) { | ||
2259 | if (ent->priv == mod) { | ||
2260 | list_del_init(&ent->list); | ||
2261 | kfree(ent); | ||
2262 | } | ||
2263 | } | ||
2264 | mutex_unlock(&kprobe_ei_mutex); | ||
2265 | } | ||
2266 | #else | ||
2267 | static inline void __init populate_kernel_kprobe_ei_list(void) {} | ||
2268 | static inline void module_load_kprobe_ei_list(struct module *m) {} | ||
2269 | static inline void module_unload_kprobe_ei_list(struct module *m) {} | ||
2270 | #endif | ||
2271 | |||
2272 | /* Module notifier call back, checking kprobes on the module */ | 2171 | /* Module notifier call back, checking kprobes on the module */ |
2273 | static int kprobes_module_callback(struct notifier_block *nb, | 2172 | static int kprobes_module_callback(struct notifier_block *nb, |
2274 | unsigned long val, void *data) | 2173 | unsigned long val, void *data) |
@@ -2279,11 +2178,6 @@ static int kprobes_module_callback(struct notifier_block *nb, | |||
2279 | unsigned int i; | 2178 | unsigned int i; |
2280 | int checkcore = (val == MODULE_STATE_GOING); | 2179 | int checkcore = (val == MODULE_STATE_GOING); |
2281 | 2180 | ||
2282 | if (val == MODULE_STATE_COMING) | ||
2283 | module_load_kprobe_ei_list(mod); | ||
2284 | else if (val == MODULE_STATE_GOING) | ||
2285 | module_unload_kprobe_ei_list(mod); | ||
2286 | |||
2287 | if (val != MODULE_STATE_GOING && val != MODULE_STATE_LIVE) | 2181 | if (val != MODULE_STATE_GOING && val != MODULE_STATE_LIVE) |
2288 | return NOTIFY_DONE; | 2182 | return NOTIFY_DONE; |
2289 | 2183 | ||
@@ -2346,8 +2240,6 @@ static int __init init_kprobes(void) | |||
2346 | pr_err("Please take care of using kprobes.\n"); | 2240 | pr_err("Please take care of using kprobes.\n"); |
2347 | } | 2241 | } |
2348 | 2242 | ||
2349 | populate_kernel_kprobe_ei_list(); | ||
2350 | |||
2351 | if (kretprobe_blacklist_size) { | 2243 | if (kretprobe_blacklist_size) { |
2352 | /* lookup the function address from its name */ | 2244 | /* lookup the function address from its name */ |
2353 | for (i = 0; kretprobe_blacklist[i].name != NULL; i++) { | 2245 | for (i = 0; kretprobe_blacklist[i].name != NULL; i++) { |
@@ -2515,56 +2407,6 @@ static const struct file_operations debugfs_kprobe_blacklist_ops = { | |||
2515 | .release = seq_release, | 2407 | .release = seq_release, |
2516 | }; | 2408 | }; |
2517 | 2409 | ||
2518 | /* | ||
2519 | * kprobes/error_injection_list -- shows which functions can be overriden for | ||
2520 | * error injection. | ||
2521 | * */ | ||
2522 | static void *kprobe_ei_seq_start(struct seq_file *m, loff_t *pos) | ||
2523 | { | ||
2524 | mutex_lock(&kprobe_ei_mutex); | ||
2525 | return seq_list_start(&kprobe_error_injection_list, *pos); | ||
2526 | } | ||
2527 | |||
2528 | static void kprobe_ei_seq_stop(struct seq_file *m, void *v) | ||
2529 | { | ||
2530 | mutex_unlock(&kprobe_ei_mutex); | ||
2531 | } | ||
2532 | |||
2533 | static void *kprobe_ei_seq_next(struct seq_file *m, void *v, loff_t *pos) | ||
2534 | { | ||
2535 | return seq_list_next(v, &kprobe_error_injection_list, pos); | ||
2536 | } | ||
2537 | |||
2538 | static int kprobe_ei_seq_show(struct seq_file *m, void *v) | ||
2539 | { | ||
2540 | char buffer[KSYM_SYMBOL_LEN]; | ||
2541 | struct kprobe_ei_entry *ent = | ||
2542 | list_entry(v, struct kprobe_ei_entry, list); | ||
2543 | |||
2544 | sprint_symbol(buffer, ent->start_addr); | ||
2545 | seq_printf(m, "%s\n", buffer); | ||
2546 | return 0; | ||
2547 | } | ||
2548 | |||
2549 | static const struct seq_operations kprobe_ei_seq_ops = { | ||
2550 | .start = kprobe_ei_seq_start, | ||
2551 | .next = kprobe_ei_seq_next, | ||
2552 | .stop = kprobe_ei_seq_stop, | ||
2553 | .show = kprobe_ei_seq_show, | ||
2554 | }; | ||
2555 | |||
2556 | static int kprobe_ei_open(struct inode *inode, struct file *filp) | ||
2557 | { | ||
2558 | return seq_open(filp, &kprobe_ei_seq_ops); | ||
2559 | } | ||
2560 | |||
2561 | static const struct file_operations debugfs_kprobe_ei_ops = { | ||
2562 | .open = kprobe_ei_open, | ||
2563 | .read = seq_read, | ||
2564 | .llseek = seq_lseek, | ||
2565 | .release = seq_release, | ||
2566 | }; | ||
2567 | |||
2568 | static void arm_all_kprobes(void) | 2410 | static void arm_all_kprobes(void) |
2569 | { | 2411 | { |
2570 | struct hlist_head *head; | 2412 | struct hlist_head *head; |
@@ -2706,11 +2548,6 @@ static int __init debugfs_kprobe_init(void) | |||
2706 | if (!file) | 2548 | if (!file) |
2707 | goto error; | 2549 | goto error; |
2708 | 2550 | ||
2709 | file = debugfs_create_file("error_injection_list", 0444, dir, NULL, | ||
2710 | &debugfs_kprobe_ei_ops); | ||
2711 | if (!file) | ||
2712 | goto error; | ||
2713 | |||
2714 | return 0; | 2551 | return 0; |
2715 | 2552 | ||
2716 | error: | 2553 | error: |