.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Kernel Probes (KProbes) |
---|
3 | 4 | * kernel/kprobes.c |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify |
---|
6 | | - * it under the terms of the GNU General Public License as published by |
---|
7 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
8 | | - * (at your option) any later version. |
---|
9 | | - * |
---|
10 | | - * This program is distributed in the hope that it will be useful, |
---|
11 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
12 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
13 | | - * GNU General Public License for more details. |
---|
14 | | - * |
---|
15 | | - * You should have received a copy of the GNU General Public License |
---|
16 | | - * along with this program; if not, write to the Free Software |
---|
17 | | - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
---|
18 | 5 | * |
---|
19 | 6 | * Copyright (C) IBM Corporation, 2002, 2004 |
---|
20 | 7 | * |
---|
.. | .. |
---|
48 | 35 | #include <linux/ftrace.h> |
---|
49 | 36 | #include <linux/cpu.h> |
---|
50 | 37 | #include <linux/jump_label.h> |
---|
| 38 | +#include <linux/perf_event.h> |
---|
| 39 | +#include <linux/static_call.h> |
---|
51 | 40 | |
---|
52 | 41 | #include <asm/sections.h> |
---|
53 | 42 | #include <asm/cacheflush.h> |
---|
.. | .. |
---|
59 | 48 | |
---|
60 | 49 | |
---|
61 | 50 | static int kprobes_initialized; |
---|
| 51 | +/* kprobe_table can be accessed by |
---|
| 52 | + * - Normal hlist traversal and RCU add/del under kprobe_mutex is held. |
---|
| 53 | + * Or |
---|
| 54 | + * - RCU hlist traversal under disabling preempt (breakpoint handlers) |
---|
| 55 | + */ |
---|
62 | 56 | static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE]; |
---|
63 | 57 | static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE]; |
---|
64 | 58 | |
---|
.. | .. |
---|
131 | 125 | .mutex = __MUTEX_INITIALIZER(kprobe_insn_slots.mutex), |
---|
132 | 126 | .alloc = alloc_insn_page, |
---|
133 | 127 | .free = free_insn_page, |
---|
| 128 | + .sym = KPROBE_INSN_PAGE_SYM, |
---|
134 | 129 | .pages = LIST_HEAD_INIT(kprobe_insn_slots.pages), |
---|
135 | 130 | .insn_size = MAX_INSN_SIZE, |
---|
136 | 131 | .nr_garbage = 0, |
---|
.. | .. |
---|
196 | 191 | kip->cache = c; |
---|
197 | 192 | list_add_rcu(&kip->list, &c->pages); |
---|
198 | 193 | slot = kip->insns; |
---|
| 194 | + |
---|
| 195 | + /* Record the perf ksymbol register event after adding the page */ |
---|
| 196 | + perf_event_ksymbol(PERF_RECORD_KSYMBOL_TYPE_OOL, (unsigned long)kip->insns, |
---|
| 197 | + PAGE_SIZE, false, c->sym); |
---|
199 | 198 | out: |
---|
200 | 199 | mutex_unlock(&c->mutex); |
---|
201 | 200 | return slot; |
---|
.. | .. |
---|
214 | 213 | * next time somebody inserts a probe. |
---|
215 | 214 | */ |
---|
216 | 215 | if (!list_is_singular(&kip->list)) { |
---|
| 216 | + /* |
---|
| 217 | + * Record perf ksymbol unregister event before removing |
---|
| 218 | + * the page. |
---|
| 219 | + */ |
---|
| 220 | + perf_event_ksymbol(PERF_RECORD_KSYMBOL_TYPE_OOL, |
---|
| 221 | + (unsigned long)kip->insns, PAGE_SIZE, true, |
---|
| 222 | + kip->cache->sym); |
---|
217 | 223 | list_del_rcu(&kip->list); |
---|
218 | 224 | synchronize_rcu(); |
---|
219 | 225 | kip->cache->free(kip->insns); |
---|
.. | .. |
---|
229 | 235 | struct kprobe_insn_page *kip, *next; |
---|
230 | 236 | |
---|
231 | 237 | /* Ensure no-one is interrupted on the garbages */ |
---|
232 | | - synchronize_sched(); |
---|
| 238 | + synchronize_rcu(); |
---|
233 | 239 | |
---|
234 | 240 | list_for_each_entry_safe(kip, next, &c->pages, list) { |
---|
235 | 241 | int i; |
---|
.. | .. |
---|
303 | 309 | return ret; |
---|
304 | 310 | } |
---|
305 | 311 | |
---|
| 312 | +int kprobe_cache_get_kallsym(struct kprobe_insn_cache *c, unsigned int *symnum, |
---|
| 313 | + unsigned long *value, char *type, char *sym) |
---|
| 314 | +{ |
---|
| 315 | + struct kprobe_insn_page *kip; |
---|
| 316 | + int ret = -ERANGE; |
---|
| 317 | + |
---|
| 318 | + rcu_read_lock(); |
---|
| 319 | + list_for_each_entry_rcu(kip, &c->pages, list) { |
---|
| 320 | + if ((*symnum)--) |
---|
| 321 | + continue; |
---|
| 322 | + strlcpy(sym, c->sym, KSYM_NAME_LEN); |
---|
| 323 | + *type = 't'; |
---|
| 324 | + *value = (unsigned long)kip->insns; |
---|
| 325 | + ret = 0; |
---|
| 326 | + break; |
---|
| 327 | + } |
---|
| 328 | + rcu_read_unlock(); |
---|
| 329 | + |
---|
| 330 | + return ret; |
---|
| 331 | +} |
---|
| 332 | + |
---|
306 | 333 | #ifdef CONFIG_OPTPROBES |
---|
307 | 334 | /* For optimized_kprobe buffer */ |
---|
308 | 335 | struct kprobe_insn_cache kprobe_optinsn_slots = { |
---|
309 | 336 | .mutex = __MUTEX_INITIALIZER(kprobe_optinsn_slots.mutex), |
---|
310 | 337 | .alloc = alloc_insn_page, |
---|
311 | 338 | .free = free_insn_page, |
---|
| 339 | + .sym = KPROBE_OPTINSN_PAGE_SYM, |
---|
312 | 340 | .pages = LIST_HEAD_INIT(kprobe_optinsn_slots.pages), |
---|
313 | 341 | /* .insn_size is initialized later */ |
---|
314 | 342 | .nr_garbage = 0, |
---|
.. | .. |
---|
339 | 367 | struct kprobe *p; |
---|
340 | 368 | |
---|
341 | 369 | head = &kprobe_table[hash_ptr(addr, KPROBE_HASH_BITS)]; |
---|
342 | | - hlist_for_each_entry_rcu(p, head, hlist) { |
---|
| 370 | + hlist_for_each_entry_rcu(p, head, hlist, |
---|
| 371 | + lockdep_is_held(&kprobe_mutex)) { |
---|
343 | 372 | if (p->addr == addr) |
---|
344 | 373 | return p; |
---|
345 | 374 | } |
---|
.. | .. |
---|
570 | 599 | mutex_lock(&kprobe_mutex); |
---|
571 | 600 | cpus_read_lock(); |
---|
572 | 601 | mutex_lock(&text_mutex); |
---|
573 | | - /* Lock modules while optimizing kprobes */ |
---|
574 | | - mutex_lock(&module_mutex); |
---|
575 | 602 | |
---|
576 | 603 | /* |
---|
577 | 604 | * Step 1: Unoptimize kprobes and collect cleaned (unused and disarmed) |
---|
.. | .. |
---|
596 | 623 | /* Step 4: Free cleaned kprobes after quiesence period */ |
---|
597 | 624 | do_free_cleaned_kprobes(); |
---|
598 | 625 | |
---|
599 | | - mutex_unlock(&module_mutex); |
---|
600 | 626 | mutex_unlock(&text_mutex); |
---|
601 | 627 | cpus_read_unlock(); |
---|
602 | 628 | |
---|
.. | .. |
---|
682 | 708 | lockdep_assert_cpus_held(); |
---|
683 | 709 | arch_unoptimize_kprobe(op); |
---|
684 | 710 | op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; |
---|
685 | | - if (kprobe_disabled(&op->kp)) |
---|
686 | | - arch_disarm_kprobe(&op->kp); |
---|
687 | 711 | } |
---|
688 | 712 | |
---|
689 | 713 | /* Unoptimize a kprobe if p is optimized */ |
---|
.. | .. |
---|
732 | 756 | { |
---|
733 | 757 | struct optimized_kprobe *op; |
---|
734 | 758 | |
---|
735 | | - BUG_ON(!kprobe_unused(ap)); |
---|
736 | 759 | /* |
---|
737 | 760 | * Unused kprobe MUST be on the way of delayed unoptimizing (means |
---|
738 | 761 | * there is still a relative jump) and disabled. |
---|
.. | .. |
---|
848 | 871 | cpus_read_unlock(); |
---|
849 | 872 | } |
---|
850 | 873 | |
---|
851 | | -#ifdef CONFIG_SYSCTL |
---|
852 | 874 | static void optimize_all_kprobes(void) |
---|
853 | 875 | { |
---|
854 | 876 | struct hlist_head *head; |
---|
.. | .. |
---|
864 | 886 | kprobes_allow_optimization = true; |
---|
865 | 887 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { |
---|
866 | 888 | head = &kprobe_table[i]; |
---|
867 | | - hlist_for_each_entry_rcu(p, head, hlist) |
---|
| 889 | + hlist_for_each_entry(p, head, hlist) |
---|
868 | 890 | if (!kprobe_disabled(p)) |
---|
869 | 891 | optimize_kprobe(p); |
---|
870 | 892 | } |
---|
.. | .. |
---|
874 | 896 | mutex_unlock(&kprobe_mutex); |
---|
875 | 897 | } |
---|
876 | 898 | |
---|
| 899 | +#ifdef CONFIG_SYSCTL |
---|
877 | 900 | static void unoptimize_all_kprobes(void) |
---|
878 | 901 | { |
---|
879 | 902 | struct hlist_head *head; |
---|
.. | .. |
---|
891 | 914 | kprobes_allow_optimization = false; |
---|
892 | 915 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { |
---|
893 | 916 | head = &kprobe_table[i]; |
---|
894 | | - hlist_for_each_entry_rcu(p, head, hlist) { |
---|
| 917 | + hlist_for_each_entry(p, head, hlist) { |
---|
895 | 918 | if (!kprobe_disabled(p)) |
---|
896 | 919 | unoptimize_kprobe(p, false); |
---|
897 | 920 | } |
---|
.. | .. |
---|
907 | 930 | static DEFINE_MUTEX(kprobe_sysctl_mutex); |
---|
908 | 931 | int sysctl_kprobes_optimization; |
---|
909 | 932 | int proc_kprobes_optimization_handler(struct ctl_table *table, int write, |
---|
910 | | - void __user *buffer, size_t *length, |
---|
| 933 | + void *buffer, size_t *length, |
---|
911 | 934 | loff_t *ppos) |
---|
912 | 935 | { |
---|
913 | 936 | int ret; |
---|
.. | .. |
---|
998 | 1021 | #ifdef CONFIG_KPROBES_ON_FTRACE |
---|
999 | 1022 | static struct ftrace_ops kprobe_ftrace_ops __read_mostly = { |
---|
1000 | 1023 | .func = kprobe_ftrace_handler, |
---|
| 1024 | + .flags = FTRACE_OPS_FL_SAVE_REGS, |
---|
| 1025 | +}; |
---|
| 1026 | + |
---|
| 1027 | +static struct ftrace_ops kprobe_ipmodify_ops __read_mostly = { |
---|
| 1028 | + .func = kprobe_ftrace_handler, |
---|
1001 | 1029 | .flags = FTRACE_OPS_FL_SAVE_REGS | FTRACE_OPS_FL_IPMODIFY, |
---|
1002 | 1030 | }; |
---|
| 1031 | + |
---|
| 1032 | +static int kprobe_ipmodify_enabled; |
---|
1003 | 1033 | static int kprobe_ftrace_enabled; |
---|
1004 | 1034 | |
---|
1005 | 1035 | /* Must ensure p->addr is really on ftrace */ |
---|
.. | .. |
---|
1012 | 1042 | } |
---|
1013 | 1043 | |
---|
1014 | 1044 | /* Caller must lock kprobe_mutex */ |
---|
1015 | | -static int arm_kprobe_ftrace(struct kprobe *p) |
---|
| 1045 | +static int __arm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops, |
---|
| 1046 | + int *cnt) |
---|
1016 | 1047 | { |
---|
1017 | 1048 | int ret = 0; |
---|
1018 | 1049 | |
---|
1019 | | - ret = ftrace_set_filter_ip(&kprobe_ftrace_ops, |
---|
1020 | | - (unsigned long)p->addr, 0, 0); |
---|
| 1050 | + ret = ftrace_set_filter_ip(ops, (unsigned long)p->addr, 0, 0); |
---|
1021 | 1051 | if (ret) { |
---|
1022 | 1052 | pr_debug("Failed to arm kprobe-ftrace at %pS (%d)\n", |
---|
1023 | 1053 | p->addr, ret); |
---|
1024 | 1054 | return ret; |
---|
1025 | 1055 | } |
---|
1026 | 1056 | |
---|
1027 | | - if (kprobe_ftrace_enabled == 0) { |
---|
1028 | | - ret = register_ftrace_function(&kprobe_ftrace_ops); |
---|
| 1057 | + if (*cnt == 0) { |
---|
| 1058 | + ret = register_ftrace_function(ops); |
---|
1029 | 1059 | if (ret) { |
---|
1030 | 1060 | pr_debug("Failed to init kprobe-ftrace (%d)\n", ret); |
---|
1031 | 1061 | goto err_ftrace; |
---|
1032 | 1062 | } |
---|
1033 | 1063 | } |
---|
1034 | 1064 | |
---|
1035 | | - kprobe_ftrace_enabled++; |
---|
| 1065 | + (*cnt)++; |
---|
1036 | 1066 | return ret; |
---|
1037 | 1067 | |
---|
1038 | 1068 | err_ftrace: |
---|
1039 | 1069 | /* |
---|
1040 | | - * Note: Since kprobe_ftrace_ops has IPMODIFY set, and ftrace requires a |
---|
1041 | | - * non-empty filter_hash for IPMODIFY ops, we're safe from an accidental |
---|
1042 | | - * empty filter_hash which would undesirably trace all functions. |
---|
| 1070 | + * At this point, sinec ops is not registered, we should be sefe from |
---|
| 1071 | + * registering empty filter. |
---|
1043 | 1072 | */ |
---|
1044 | | - ftrace_set_filter_ip(&kprobe_ftrace_ops, (unsigned long)p->addr, 1, 0); |
---|
| 1073 | + ftrace_set_filter_ip(ops, (unsigned long)p->addr, 1, 0); |
---|
1045 | 1074 | return ret; |
---|
1046 | 1075 | } |
---|
1047 | 1076 | |
---|
| 1077 | +static int arm_kprobe_ftrace(struct kprobe *p) |
---|
| 1078 | +{ |
---|
| 1079 | + bool ipmodify = (p->post_handler != NULL); |
---|
| 1080 | + |
---|
| 1081 | + return __arm_kprobe_ftrace(p, |
---|
| 1082 | + ipmodify ? &kprobe_ipmodify_ops : &kprobe_ftrace_ops, |
---|
| 1083 | + ipmodify ? &kprobe_ipmodify_enabled : &kprobe_ftrace_enabled); |
---|
| 1084 | +} |
---|
| 1085 | + |
---|
1048 | 1086 | /* Caller must lock kprobe_mutex */ |
---|
1049 | | -static int disarm_kprobe_ftrace(struct kprobe *p) |
---|
| 1087 | +static int __disarm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops, |
---|
| 1088 | + int *cnt) |
---|
1050 | 1089 | { |
---|
1051 | 1090 | int ret = 0; |
---|
1052 | 1091 | |
---|
1053 | | - if (kprobe_ftrace_enabled == 1) { |
---|
1054 | | - ret = unregister_ftrace_function(&kprobe_ftrace_ops); |
---|
| 1092 | + if (*cnt == 1) { |
---|
| 1093 | + ret = unregister_ftrace_function(ops); |
---|
1055 | 1094 | if (WARN(ret < 0, "Failed to unregister kprobe-ftrace (%d)\n", ret)) |
---|
1056 | 1095 | return ret; |
---|
1057 | 1096 | } |
---|
1058 | 1097 | |
---|
1059 | | - kprobe_ftrace_enabled--; |
---|
| 1098 | + (*cnt)--; |
---|
1060 | 1099 | |
---|
1061 | | - ret = ftrace_set_filter_ip(&kprobe_ftrace_ops, |
---|
1062 | | - (unsigned long)p->addr, 1, 0); |
---|
| 1100 | + ret = ftrace_set_filter_ip(ops, (unsigned long)p->addr, 1, 0); |
---|
1063 | 1101 | WARN_ONCE(ret < 0, "Failed to disarm kprobe-ftrace at %pS (%d)\n", |
---|
1064 | 1102 | p->addr, ret); |
---|
1065 | 1103 | return ret; |
---|
| 1104 | +} |
---|
| 1105 | + |
---|
| 1106 | +static int disarm_kprobe_ftrace(struct kprobe *p) |
---|
| 1107 | +{ |
---|
| 1108 | + bool ipmodify = (p->post_handler != NULL); |
---|
| 1109 | + |
---|
| 1110 | + return __disarm_kprobe_ftrace(p, |
---|
| 1111 | + ipmodify ? &kprobe_ipmodify_ops : &kprobe_ftrace_ops, |
---|
| 1112 | + ipmodify ? &kprobe_ipmodify_enabled : &kprobe_ftrace_enabled); |
---|
1066 | 1113 | } |
---|
1067 | 1114 | #else /* !CONFIG_KPROBES_ON_FTRACE */ |
---|
1068 | 1115 | static inline int prepare_kprobe(struct kprobe *p) |
---|
.. | .. |
---|
1177 | 1224 | } |
---|
1178 | 1225 | NOKPROBE_SYMBOL(kprobes_inc_nmissed_count); |
---|
1179 | 1226 | |
---|
1180 | | -void recycle_rp_inst(struct kretprobe_instance *ri, |
---|
1181 | | - struct hlist_head *head) |
---|
| 1227 | +static void recycle_rp_inst(struct kretprobe_instance *ri) |
---|
1182 | 1228 | { |
---|
1183 | 1229 | struct kretprobe *rp = ri->rp; |
---|
1184 | 1230 | |
---|
.. | .. |
---|
1190 | 1236 | hlist_add_head(&ri->hlist, &rp->free_instances); |
---|
1191 | 1237 | raw_spin_unlock(&rp->lock); |
---|
1192 | 1238 | } else |
---|
1193 | | - /* Unregistering */ |
---|
1194 | | - hlist_add_head(&ri->hlist, head); |
---|
| 1239 | + kfree_rcu(ri, rcu); |
---|
1195 | 1240 | } |
---|
1196 | 1241 | NOKPROBE_SYMBOL(recycle_rp_inst); |
---|
1197 | 1242 | |
---|
1198 | | -void kretprobe_hash_lock(struct task_struct *tsk, |
---|
| 1243 | +static void kretprobe_hash_lock(struct task_struct *tsk, |
---|
1199 | 1244 | struct hlist_head **head, unsigned long *flags) |
---|
1200 | 1245 | __acquires(hlist_lock) |
---|
1201 | 1246 | { |
---|
.. | .. |
---|
1204 | 1249 | |
---|
1205 | 1250 | *head = &kretprobe_inst_table[hash]; |
---|
1206 | 1251 | hlist_lock = kretprobe_table_lock_ptr(hash); |
---|
1207 | | - raw_spin_lock_irqsave(hlist_lock, *flags); |
---|
| 1252 | + /* |
---|
| 1253 | + * Nested is a workaround that will soon not be needed. |
---|
| 1254 | + * There's other protections that make sure the same lock |
---|
| 1255 | + * is not taken on the same CPU that lockdep is unaware of. |
---|
| 1256 | + * Differentiate when it is taken in NMI context. |
---|
| 1257 | + */ |
---|
| 1258 | + raw_spin_lock_irqsave_nested(hlist_lock, *flags, !!in_nmi()); |
---|
1208 | 1259 | } |
---|
1209 | 1260 | NOKPROBE_SYMBOL(kretprobe_hash_lock); |
---|
1210 | 1261 | |
---|
.. | .. |
---|
1213 | 1264 | __acquires(hlist_lock) |
---|
1214 | 1265 | { |
---|
1215 | 1266 | raw_spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash); |
---|
1216 | | - raw_spin_lock_irqsave(hlist_lock, *flags); |
---|
| 1267 | + /* |
---|
| 1268 | + * Nested is a workaround that will soon not be needed. |
---|
| 1269 | + * There's other protections that make sure the same lock |
---|
| 1270 | + * is not taken on the same CPU that lockdep is unaware of. |
---|
| 1271 | + * Differentiate when it is taken in NMI context. |
---|
| 1272 | + */ |
---|
| 1273 | + raw_spin_lock_irqsave_nested(hlist_lock, *flags, !!in_nmi()); |
---|
1217 | 1274 | } |
---|
1218 | 1275 | NOKPROBE_SYMBOL(kretprobe_table_lock); |
---|
1219 | 1276 | |
---|
1220 | | -void kretprobe_hash_unlock(struct task_struct *tsk, |
---|
| 1277 | +static void kretprobe_hash_unlock(struct task_struct *tsk, |
---|
1221 | 1278 | unsigned long *flags) |
---|
1222 | 1279 | __releases(hlist_lock) |
---|
1223 | 1280 | { |
---|
.. | .. |
---|
1238 | 1295 | } |
---|
1239 | 1296 | NOKPROBE_SYMBOL(kretprobe_table_unlock); |
---|
1240 | 1297 | |
---|
1241 | | -struct kprobe kprobe_busy = { |
---|
| 1298 | +static struct kprobe kprobe_busy = { |
---|
1242 | 1299 | .addr = (void *) get_kprobe, |
---|
1243 | 1300 | }; |
---|
1244 | 1301 | |
---|
.. | .. |
---|
1267 | 1324 | void kprobe_flush_task(struct task_struct *tk) |
---|
1268 | 1325 | { |
---|
1269 | 1326 | struct kretprobe_instance *ri; |
---|
1270 | | - struct hlist_head *head, empty_rp; |
---|
| 1327 | + struct hlist_head *head; |
---|
1271 | 1328 | struct hlist_node *tmp; |
---|
1272 | 1329 | unsigned long hash, flags = 0; |
---|
1273 | 1330 | |
---|
.. | .. |
---|
1277 | 1334 | |
---|
1278 | 1335 | kprobe_busy_begin(); |
---|
1279 | 1336 | |
---|
1280 | | - INIT_HLIST_HEAD(&empty_rp); |
---|
1281 | 1337 | hash = hash_ptr(tk, KPROBE_HASH_BITS); |
---|
1282 | 1338 | head = &kretprobe_inst_table[hash]; |
---|
1283 | 1339 | kretprobe_table_lock(hash, &flags); |
---|
1284 | 1340 | hlist_for_each_entry_safe(ri, tmp, head, hlist) { |
---|
1285 | 1341 | if (ri->task == tk) |
---|
1286 | | - recycle_rp_inst(ri, &empty_rp); |
---|
| 1342 | + recycle_rp_inst(ri); |
---|
1287 | 1343 | } |
---|
1288 | 1344 | kretprobe_table_unlock(hash, &flags); |
---|
1289 | | - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { |
---|
1290 | | - hlist_del(&ri->hlist); |
---|
1291 | | - kfree(ri); |
---|
1292 | | - } |
---|
1293 | 1345 | |
---|
1294 | 1346 | kprobe_busy_end(); |
---|
1295 | 1347 | } |
---|
.. | .. |
---|
1313 | 1365 | struct hlist_node *next; |
---|
1314 | 1366 | struct hlist_head *head; |
---|
1315 | 1367 | |
---|
1316 | | - /* No race here */ |
---|
| 1368 | + /* To avoid recursive kretprobe by NMI, set kprobe busy here */ |
---|
| 1369 | + kprobe_busy_begin(); |
---|
1317 | 1370 | for (hash = 0; hash < KPROBE_TABLE_SIZE; hash++) { |
---|
1318 | 1371 | kretprobe_table_lock(hash, &flags); |
---|
1319 | 1372 | head = &kretprobe_inst_table[hash]; |
---|
.. | .. |
---|
1323 | 1376 | } |
---|
1324 | 1377 | kretprobe_table_unlock(hash, &flags); |
---|
1325 | 1378 | } |
---|
| 1379 | + kprobe_busy_end(); |
---|
| 1380 | + |
---|
1326 | 1381 | free_rp_inst(rp); |
---|
1327 | 1382 | } |
---|
1328 | 1383 | NOKPROBE_SYMBOL(cleanup_rp_inst); |
---|
.. | .. |
---|
1330 | 1385 | /* Add the new probe to ap->list */ |
---|
1331 | 1386 | static int add_new_kprobe(struct kprobe *ap, struct kprobe *p) |
---|
1332 | 1387 | { |
---|
1333 | | - BUG_ON(kprobe_gone(ap) || kprobe_gone(p)); |
---|
1334 | | - |
---|
1335 | 1388 | if (p->post_handler) |
---|
1336 | 1389 | unoptimize_kprobe(ap, true); /* Fall back to normal kprobe */ |
---|
1337 | 1390 | |
---|
.. | .. |
---|
1440 | 1493 | if (ret) { |
---|
1441 | 1494 | ap->flags |= KPROBE_FLAG_DISABLED; |
---|
1442 | 1495 | list_del_rcu(&p->list); |
---|
1443 | | - synchronize_sched(); |
---|
| 1496 | + synchronize_rcu(); |
---|
1444 | 1497 | } |
---|
1445 | 1498 | } |
---|
1446 | 1499 | } |
---|
.. | .. |
---|
1454 | 1507 | addr < (unsigned long)__kprobes_text_end; |
---|
1455 | 1508 | } |
---|
1456 | 1509 | |
---|
1457 | | -bool within_kprobe_blacklist(unsigned long addr) |
---|
| 1510 | +static bool __within_kprobe_blacklist(unsigned long addr) |
---|
1458 | 1511 | { |
---|
1459 | 1512 | struct kprobe_blacklist_entry *ent; |
---|
1460 | 1513 | |
---|
.. | .. |
---|
1468 | 1521 | if (addr >= ent->start_addr && addr < ent->end_addr) |
---|
1469 | 1522 | return true; |
---|
1470 | 1523 | } |
---|
| 1524 | + return false; |
---|
| 1525 | +} |
---|
1471 | 1526 | |
---|
| 1527 | +bool within_kprobe_blacklist(unsigned long addr) |
---|
| 1528 | +{ |
---|
| 1529 | + char symname[KSYM_NAME_LEN], *p; |
---|
| 1530 | + |
---|
| 1531 | + if (__within_kprobe_blacklist(addr)) |
---|
| 1532 | + return true; |
---|
| 1533 | + |
---|
| 1534 | + /* Check if the address is on a suffixed-symbol */ |
---|
| 1535 | + if (!lookup_symbol_name(addr, symname)) { |
---|
| 1536 | + p = strchr(symname, '.'); |
---|
| 1537 | + if (!p) |
---|
| 1538 | + return false; |
---|
| 1539 | + *p = '\0'; |
---|
| 1540 | + addr = (unsigned long)kprobe_lookup_name(symname, 0); |
---|
| 1541 | + if (addr) |
---|
| 1542 | + return __within_kprobe_blacklist(addr); |
---|
| 1543 | + } |
---|
1472 | 1544 | return false; |
---|
1473 | 1545 | } |
---|
1474 | 1546 | |
---|
.. | .. |
---|
1508 | 1580 | { |
---|
1509 | 1581 | struct kprobe *ap, *list_p; |
---|
1510 | 1582 | |
---|
| 1583 | + lockdep_assert_held(&kprobe_mutex); |
---|
| 1584 | + |
---|
1511 | 1585 | ap = get_kprobe(p->addr); |
---|
1512 | 1586 | if (unlikely(!ap)) |
---|
1513 | 1587 | return NULL; |
---|
1514 | 1588 | |
---|
1515 | 1589 | if (p != ap) { |
---|
1516 | | - list_for_each_entry_rcu(list_p, &ap->list, list) |
---|
| 1590 | + list_for_each_entry(list_p, &ap->list, list) |
---|
1517 | 1591 | if (list_p == p) |
---|
1518 | 1592 | /* kprobe p is a valid probe */ |
---|
1519 | 1593 | goto valid; |
---|
.. | .. |
---|
1566 | 1640 | preempt_disable(); |
---|
1567 | 1641 | |
---|
1568 | 1642 | /* Ensure it is not in reserved area nor out of text */ |
---|
1569 | | - if (!kernel_text_address((unsigned long) p->addr) || |
---|
| 1643 | + if (!(core_kernel_text((unsigned long) p->addr) || |
---|
| 1644 | + is_module_text_address((unsigned long) p->addr)) || |
---|
| 1645 | + in_gate_area_no_mm((unsigned long) p->addr) || |
---|
1570 | 1646 | within_kprobe_blacklist((unsigned long) p->addr) || |
---|
1571 | 1647 | jump_label_text_reserved(p->addr, p->addr) || |
---|
| 1648 | + static_call_text_reserved(p->addr, p->addr) || |
---|
1572 | 1649 | find_bug((unsigned long)p->addr)) { |
---|
1573 | 1650 | ret = -EINVAL; |
---|
1574 | 1651 | goto out; |
---|
.. | .. |
---|
1656 | 1733 | ret = arm_kprobe(p); |
---|
1657 | 1734 | if (ret) { |
---|
1658 | 1735 | hlist_del_rcu(&p->hlist); |
---|
1659 | | - synchronize_sched(); |
---|
| 1736 | + synchronize_rcu(); |
---|
1660 | 1737 | goto out; |
---|
1661 | 1738 | } |
---|
1662 | 1739 | } |
---|
.. | .. |
---|
1678 | 1755 | { |
---|
1679 | 1756 | struct kprobe *kp; |
---|
1680 | 1757 | |
---|
1681 | | - list_for_each_entry_rcu(kp, &ap->list, list) |
---|
| 1758 | + lockdep_assert_held(&kprobe_mutex); |
---|
| 1759 | + |
---|
| 1760 | + list_for_each_entry(kp, &ap->list, list) |
---|
1682 | 1761 | if (!kprobe_disabled(kp)) |
---|
1683 | 1762 | /* |
---|
1684 | 1763 | * There is an active probe on the list. |
---|
.. | .. |
---|
1708 | 1787 | /* Try to disarm and disable this/parent probe */ |
---|
1709 | 1788 | if (p == orig_p || aggr_kprobe_disabled(orig_p)) { |
---|
1710 | 1789 | /* |
---|
1711 | | - * If kprobes_all_disarmed is set, orig_p |
---|
1712 | | - * should have already been disarmed, so |
---|
1713 | | - * skip unneed disarming process. |
---|
| 1790 | + * Don't be lazy here. Even if 'kprobes_all_disarmed' |
---|
| 1791 | + * is false, 'orig_p' might not have been armed yet. |
---|
| 1792 | + * Note arm_all_kprobes() __tries__ to arm all kprobes |
---|
| 1793 | + * on the best effort basis. |
---|
1714 | 1794 | */ |
---|
1715 | | - if (!kprobes_all_disarmed) { |
---|
| 1795 | + if (!kprobes_all_disarmed && !kprobe_disabled(orig_p)) { |
---|
1716 | 1796 | ret = disarm_kprobe(orig_p, true); |
---|
1717 | 1797 | if (ret) { |
---|
1718 | 1798 | p->flags &= ~KPROBE_FLAG_DISABLED; |
---|
.. | .. |
---|
1757 | 1837 | else { |
---|
1758 | 1838 | /* If disabling probe has special handlers, update aggrprobe */ |
---|
1759 | 1839 | if (p->post_handler && !kprobe_gone(p)) { |
---|
1760 | | - list_for_each_entry_rcu(list_p, &ap->list, list) { |
---|
| 1840 | + list_for_each_entry(list_p, &ap->list, list) { |
---|
1761 | 1841 | if ((list_p != p) && (list_p->post_handler)) |
---|
1762 | 1842 | goto noclean; |
---|
1763 | 1843 | } |
---|
1764 | | - ap->post_handler = NULL; |
---|
| 1844 | + /* |
---|
| 1845 | + * For the kprobe-on-ftrace case, we keep the |
---|
| 1846 | + * post_handler setting to identify this aggrprobe |
---|
| 1847 | + * armed with kprobe_ipmodify_ops. |
---|
| 1848 | + */ |
---|
| 1849 | + if (!kprobe_ftrace(ap)) |
---|
| 1850 | + ap->post_handler = NULL; |
---|
1765 | 1851 | } |
---|
1766 | 1852 | noclean: |
---|
1767 | 1853 | /* |
---|
.. | .. |
---|
1779 | 1865 | return 0; |
---|
1780 | 1866 | |
---|
1781 | 1867 | disarmed: |
---|
1782 | | - BUG_ON(!kprobe_disarmed(ap)); |
---|
1783 | 1868 | hlist_del_rcu(&ap->hlist); |
---|
1784 | 1869 | return 0; |
---|
1785 | 1870 | } |
---|
.. | .. |
---|
1836 | 1921 | kps[i]->addr = NULL; |
---|
1837 | 1922 | mutex_unlock(&kprobe_mutex); |
---|
1838 | 1923 | |
---|
1839 | | - synchronize_sched(); |
---|
| 1924 | + synchronize_rcu(); |
---|
1840 | 1925 | for (i = 0; i < num; i++) |
---|
1841 | 1926 | if (kps[i]->addr) |
---|
1842 | 1927 | __unregister_kprobe_bottom(kps[i]); |
---|
.. | .. |
---|
1861 | 1946 | } |
---|
1862 | 1947 | |
---|
1863 | 1948 | #ifdef CONFIG_KRETPROBES |
---|
| 1949 | + |
---|
| 1950 | +unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs, |
---|
| 1951 | + void *trampoline_address, |
---|
| 1952 | + void *frame_pointer) |
---|
| 1953 | +{ |
---|
| 1954 | + struct kretprobe_instance *ri = NULL, *last = NULL; |
---|
| 1955 | + struct hlist_head *head; |
---|
| 1956 | + struct hlist_node *tmp; |
---|
| 1957 | + unsigned long flags; |
---|
| 1958 | + kprobe_opcode_t *correct_ret_addr = NULL; |
---|
| 1959 | + bool skipped = false; |
---|
| 1960 | + |
---|
| 1961 | + kretprobe_hash_lock(current, &head, &flags); |
---|
| 1962 | + |
---|
| 1963 | + /* |
---|
| 1964 | + * It is possible to have multiple instances associated with a given |
---|
| 1965 | + * task either because multiple functions in the call path have |
---|
| 1966 | + * return probes installed on them, and/or more than one |
---|
| 1967 | + * return probe was registered for a target function. |
---|
| 1968 | + * |
---|
| 1969 | + * We can handle this because: |
---|
| 1970 | + * - instances are always pushed into the head of the list |
---|
| 1971 | + * - when multiple return probes are registered for the same |
---|
| 1972 | + * function, the (chronologically) first instance's ret_addr |
---|
| 1973 | + * will be the real return address, and all the rest will |
---|
| 1974 | + * point to kretprobe_trampoline. |
---|
| 1975 | + */ |
---|
| 1976 | + hlist_for_each_entry(ri, head, hlist) { |
---|
| 1977 | + if (ri->task != current) |
---|
| 1978 | + /* another task is sharing our hash bucket */ |
---|
| 1979 | + continue; |
---|
| 1980 | + /* |
---|
| 1981 | + * Return probes must be pushed on this hash list correct |
---|
| 1982 | + * order (same as return order) so that it can be popped |
---|
| 1983 | + * correctly. However, if we find it is pushed it incorrect |
---|
| 1984 | + * order, this means we find a function which should not be |
---|
| 1985 | + * probed, because the wrong order entry is pushed on the |
---|
| 1986 | + * path of processing other kretprobe itself. |
---|
| 1987 | + */ |
---|
| 1988 | + if (ri->fp != frame_pointer) { |
---|
| 1989 | + if (!skipped) |
---|
| 1990 | + pr_warn("kretprobe is stacked incorrectly. Trying to fixup.\n"); |
---|
| 1991 | + skipped = true; |
---|
| 1992 | + continue; |
---|
| 1993 | + } |
---|
| 1994 | + |
---|
| 1995 | + correct_ret_addr = ri->ret_addr; |
---|
| 1996 | + if (skipped) |
---|
| 1997 | + pr_warn("%ps must be blacklisted because of incorrect kretprobe order\n", |
---|
| 1998 | + ri->rp->kp.addr); |
---|
| 1999 | + |
---|
| 2000 | + if (correct_ret_addr != trampoline_address) |
---|
| 2001 | + /* |
---|
| 2002 | + * This is the real return address. Any other |
---|
| 2003 | + * instances associated with this task are for |
---|
| 2004 | + * other calls deeper on the call stack |
---|
| 2005 | + */ |
---|
| 2006 | + break; |
---|
| 2007 | + } |
---|
| 2008 | + |
---|
| 2009 | + BUG_ON(!correct_ret_addr || (correct_ret_addr == trampoline_address)); |
---|
| 2010 | + last = ri; |
---|
| 2011 | + |
---|
| 2012 | + hlist_for_each_entry_safe(ri, tmp, head, hlist) { |
---|
| 2013 | + if (ri->task != current) |
---|
| 2014 | + /* another task is sharing our hash bucket */ |
---|
| 2015 | + continue; |
---|
| 2016 | + if (ri->fp != frame_pointer) |
---|
| 2017 | + continue; |
---|
| 2018 | + |
---|
| 2019 | + if (ri->rp && ri->rp->handler) { |
---|
| 2020 | + struct kprobe *prev = kprobe_running(); |
---|
| 2021 | + |
---|
| 2022 | + __this_cpu_write(current_kprobe, &ri->rp->kp); |
---|
| 2023 | + ri->ret_addr = correct_ret_addr; |
---|
| 2024 | + ri->rp->handler(ri, regs); |
---|
| 2025 | + __this_cpu_write(current_kprobe, prev); |
---|
| 2026 | + } |
---|
| 2027 | + |
---|
| 2028 | + recycle_rp_inst(ri); |
---|
| 2029 | + |
---|
| 2030 | + if (ri == last) |
---|
| 2031 | + break; |
---|
| 2032 | + } |
---|
| 2033 | + |
---|
| 2034 | + kretprobe_hash_unlock(current, &flags); |
---|
| 2035 | + |
---|
| 2036 | + return (unsigned long)correct_ret_addr; |
---|
| 2037 | +} |
---|
| 2038 | +NOKPROBE_SYMBOL(__kretprobe_trampoline_handler) |
---|
| 2039 | + |
---|
1864 | 2040 | /* |
---|
1865 | 2041 | * This kprobe pre_handler is registered with every kretprobe. When probe |
---|
1866 | 2042 | * hits it will set up the return probe. |
---|
.. | .. |
---|
1871 | 2047 | unsigned long hash, flags = 0; |
---|
1872 | 2048 | struct kretprobe_instance *ri; |
---|
1873 | 2049 | |
---|
1874 | | - /* |
---|
1875 | | - * To avoid deadlocks, prohibit return probing in NMI contexts, |
---|
1876 | | - * just skip the probe and increase the (inexact) 'nmissed' |
---|
1877 | | - * statistical counter, so that the user is informed that |
---|
1878 | | - * something happened: |
---|
1879 | | - */ |
---|
1880 | | - if (unlikely(in_nmi())) { |
---|
1881 | | - rp->nmissed++; |
---|
1882 | | - return 0; |
---|
1883 | | - } |
---|
1884 | | - |
---|
1885 | 2050 | /* TODO: consider to only swap the RA after the last pre_handler fired */ |
---|
1886 | 2051 | hash = hash_ptr(current, KPROBE_HASH_BITS); |
---|
1887 | | - raw_spin_lock_irqsave(&rp->lock, flags); |
---|
| 2052 | + /* |
---|
| 2053 | + * Nested is a workaround that will soon not be needed. |
---|
| 2054 | + * There's other protections that make sure the same lock |
---|
| 2055 | + * is not taken on the same CPU that lockdep is unaware of. |
---|
| 2056 | + */ |
---|
| 2057 | + raw_spin_lock_irqsave_nested(&rp->lock, flags, 1); |
---|
1888 | 2058 | if (!hlist_empty(&rp->free_instances)) { |
---|
1889 | 2059 | ri = hlist_entry(rp->free_instances.first, |
---|
1890 | 2060 | struct kretprobe_instance, hlist); |
---|
.. | .. |
---|
1895 | 2065 | ri->task = current; |
---|
1896 | 2066 | |
---|
1897 | 2067 | if (rp->entry_handler && rp->entry_handler(ri, regs)) { |
---|
1898 | | - raw_spin_lock_irqsave(&rp->lock, flags); |
---|
| 2068 | + raw_spin_lock_irqsave_nested(&rp->lock, flags, 1); |
---|
1899 | 2069 | hlist_add_head(&ri->hlist, &rp->free_instances); |
---|
1900 | 2070 | raw_spin_unlock_irqrestore(&rp->lock, flags); |
---|
1901 | 2071 | return 0; |
---|
.. | .. |
---|
1985 | 2155 | |
---|
1986 | 2156 | /* Pre-allocate memory for max kretprobe instances */ |
---|
1987 | 2157 | if (rp->maxactive <= 0) { |
---|
1988 | | -#ifdef CONFIG_PREEMPT |
---|
| 2158 | +#ifdef CONFIG_PREEMPTION |
---|
1989 | 2159 | rp->maxactive = max_t(unsigned int, 10, 2*num_possible_cpus()); |
---|
1990 | 2160 | #else |
---|
1991 | 2161 | rp->maxactive = num_possible_cpus(); |
---|
.. | .. |
---|
2049 | 2219 | rps[i]->kp.addr = NULL; |
---|
2050 | 2220 | mutex_unlock(&kprobe_mutex); |
---|
2051 | 2221 | |
---|
2052 | | - synchronize_sched(); |
---|
| 2222 | + synchronize_rcu(); |
---|
2053 | 2223 | for (i = 0; i < num; i++) { |
---|
2054 | 2224 | if (rps[i]->kp.addr) { |
---|
2055 | 2225 | __unregister_kprobe_bottom(&rps[i]->kp); |
---|
.. | .. |
---|
2095 | 2265 | { |
---|
2096 | 2266 | struct kprobe *kp; |
---|
2097 | 2267 | |
---|
| 2268 | + lockdep_assert_held(&kprobe_mutex); |
---|
| 2269 | + |
---|
2098 | 2270 | if (WARN_ON_ONCE(kprobe_gone(p))) |
---|
2099 | 2271 | return; |
---|
2100 | 2272 | |
---|
.. | .. |
---|
2104 | 2276 | * If this is an aggr_kprobe, we have to list all the |
---|
2105 | 2277 | * chained probes and mark them GONE. |
---|
2106 | 2278 | */ |
---|
2107 | | - list_for_each_entry_rcu(kp, &p->list, list) |
---|
| 2279 | + list_for_each_entry(kp, &p->list, list) |
---|
2108 | 2280 | kp->flags |= KPROBE_FLAG_GONE; |
---|
2109 | 2281 | p->post_handler = NULL; |
---|
2110 | 2282 | kill_optimized_kprobe(p); |
---|
.. | .. |
---|
2169 | 2341 | if (!kprobes_all_disarmed && kprobe_disabled(p)) { |
---|
2170 | 2342 | p->flags &= ~KPROBE_FLAG_DISABLED; |
---|
2171 | 2343 | ret = arm_kprobe(p); |
---|
2172 | | - if (ret) |
---|
| 2344 | + if (ret) { |
---|
2173 | 2345 | p->flags |= KPROBE_FLAG_DISABLED; |
---|
| 2346 | + if (p != kp) |
---|
| 2347 | + kp->flags |= KPROBE_FLAG_DISABLED; |
---|
| 2348 | + } |
---|
2174 | 2349 | } |
---|
2175 | 2350 | out: |
---|
2176 | 2351 | mutex_unlock(&kprobe_mutex); |
---|
.. | .. |
---|
2223 | 2398 | return 0; |
---|
2224 | 2399 | } |
---|
2225 | 2400 | |
---|
| 2401 | +/* Remove all symbols in given area from kprobe blacklist */ |
---|
| 2402 | +static void kprobe_remove_area_blacklist(unsigned long start, unsigned long end) |
---|
| 2403 | +{ |
---|
| 2404 | + struct kprobe_blacklist_entry *ent, *n; |
---|
| 2405 | + |
---|
| 2406 | + list_for_each_entry_safe(ent, n, &kprobe_blacklist, list) { |
---|
| 2407 | + if (ent->start_addr < start || ent->start_addr >= end) |
---|
| 2408 | + continue; |
---|
| 2409 | + list_del(&ent->list); |
---|
| 2410 | + kfree(ent); |
---|
| 2411 | + } |
---|
| 2412 | +} |
---|
| 2413 | + |
---|
| 2414 | +static void kprobe_remove_ksym_blacklist(unsigned long entry) |
---|
| 2415 | +{ |
---|
| 2416 | + kprobe_remove_area_blacklist(entry, entry + 1); |
---|
| 2417 | +} |
---|
| 2418 | + |
---|
| 2419 | +int __weak arch_kprobe_get_kallsym(unsigned int *symnum, unsigned long *value, |
---|
| 2420 | + char *type, char *sym) |
---|
| 2421 | +{ |
---|
| 2422 | + return -ERANGE; |
---|
| 2423 | +} |
---|
| 2424 | + |
---|
| 2425 | +int kprobe_get_kallsym(unsigned int symnum, unsigned long *value, char *type, |
---|
| 2426 | + char *sym) |
---|
| 2427 | +{ |
---|
| 2428 | +#ifdef __ARCH_WANT_KPROBES_INSN_SLOT |
---|
| 2429 | + if (!kprobe_cache_get_kallsym(&kprobe_insn_slots, &symnum, value, type, sym)) |
---|
| 2430 | + return 0; |
---|
| 2431 | +#ifdef CONFIG_OPTPROBES |
---|
| 2432 | + if (!kprobe_cache_get_kallsym(&kprobe_optinsn_slots, &symnum, value, type, sym)) |
---|
| 2433 | + return 0; |
---|
| 2434 | +#endif |
---|
| 2435 | +#endif |
---|
| 2436 | + if (!arch_kprobe_get_kallsym(&symnum, value, type, sym)) |
---|
| 2437 | + return 0; |
---|
| 2438 | + return -ERANGE; |
---|
| 2439 | +} |
---|
| 2440 | + |
---|
2226 | 2441 | int __init __weak arch_populate_kprobe_blacklist(void) |
---|
2227 | 2442 | { |
---|
2228 | 2443 | return 0; |
---|
.. | .. |
---|
2255 | 2470 | /* Symbols in __kprobes_text are blacklisted */ |
---|
2256 | 2471 | ret = kprobe_add_area_blacklist((unsigned long)__kprobes_text_start, |
---|
2257 | 2472 | (unsigned long)__kprobes_text_end); |
---|
| 2473 | + if (ret) |
---|
| 2474 | + return ret; |
---|
| 2475 | + |
---|
| 2476 | + /* Symbols in noinstr section are blacklisted */ |
---|
| 2477 | + ret = kprobe_add_area_blacklist((unsigned long)__noinstr_text_start, |
---|
| 2478 | + (unsigned long)__noinstr_text_end); |
---|
2258 | 2479 | |
---|
2259 | 2480 | return ret ? : arch_populate_kprobe_blacklist(); |
---|
| 2481 | +} |
---|
| 2482 | + |
---|
| 2483 | +static void add_module_kprobe_blacklist(struct module *mod) |
---|
| 2484 | +{ |
---|
| 2485 | + unsigned long start, end; |
---|
| 2486 | + int i; |
---|
| 2487 | + |
---|
| 2488 | + if (mod->kprobe_blacklist) { |
---|
| 2489 | + for (i = 0; i < mod->num_kprobe_blacklist; i++) |
---|
| 2490 | + kprobe_add_ksym_blacklist(mod->kprobe_blacklist[i]); |
---|
| 2491 | + } |
---|
| 2492 | + |
---|
| 2493 | + start = (unsigned long)mod->kprobes_text_start; |
---|
| 2494 | + if (start) { |
---|
| 2495 | + end = start + mod->kprobes_text_size; |
---|
| 2496 | + kprobe_add_area_blacklist(start, end); |
---|
| 2497 | + } |
---|
| 2498 | + |
---|
| 2499 | + start = (unsigned long)mod->noinstr_text_start; |
---|
| 2500 | + if (start) { |
---|
| 2501 | + end = start + mod->noinstr_text_size; |
---|
| 2502 | + kprobe_add_area_blacklist(start, end); |
---|
| 2503 | + } |
---|
| 2504 | +} |
---|
| 2505 | + |
---|
| 2506 | +static void remove_module_kprobe_blacklist(struct module *mod) |
---|
| 2507 | +{ |
---|
| 2508 | + unsigned long start, end; |
---|
| 2509 | + int i; |
---|
| 2510 | + |
---|
| 2511 | + if (mod->kprobe_blacklist) { |
---|
| 2512 | + for (i = 0; i < mod->num_kprobe_blacklist; i++) |
---|
| 2513 | + kprobe_remove_ksym_blacklist(mod->kprobe_blacklist[i]); |
---|
| 2514 | + } |
---|
| 2515 | + |
---|
| 2516 | + start = (unsigned long)mod->kprobes_text_start; |
---|
| 2517 | + if (start) { |
---|
| 2518 | + end = start + mod->kprobes_text_size; |
---|
| 2519 | + kprobe_remove_area_blacklist(start, end); |
---|
| 2520 | + } |
---|
| 2521 | + |
---|
| 2522 | + start = (unsigned long)mod->noinstr_text_start; |
---|
| 2523 | + if (start) { |
---|
| 2524 | + end = start + mod->noinstr_text_size; |
---|
| 2525 | + kprobe_remove_area_blacklist(start, end); |
---|
| 2526 | + } |
---|
2260 | 2527 | } |
---|
2261 | 2528 | |
---|
2262 | 2529 | /* Module notifier call back, checking kprobes on the module */ |
---|
.. | .. |
---|
2269 | 2536 | unsigned int i; |
---|
2270 | 2537 | int checkcore = (val == MODULE_STATE_GOING); |
---|
2271 | 2538 | |
---|
| 2539 | + if (val == MODULE_STATE_COMING) { |
---|
| 2540 | + mutex_lock(&kprobe_mutex); |
---|
| 2541 | + add_module_kprobe_blacklist(mod); |
---|
| 2542 | + mutex_unlock(&kprobe_mutex); |
---|
| 2543 | + } |
---|
2272 | 2544 | if (val != MODULE_STATE_GOING && val != MODULE_STATE_LIVE) |
---|
2273 | 2545 | return NOTIFY_DONE; |
---|
2274 | 2546 | |
---|
.. | .. |
---|
2281 | 2553 | mutex_lock(&kprobe_mutex); |
---|
2282 | 2554 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { |
---|
2283 | 2555 | head = &kprobe_table[i]; |
---|
2284 | | - hlist_for_each_entry_rcu(p, head, hlist) { |
---|
| 2556 | + hlist_for_each_entry(p, head, hlist) { |
---|
2285 | 2557 | if (kprobe_gone(p)) |
---|
2286 | 2558 | continue; |
---|
2287 | 2559 | |
---|
.. | .. |
---|
2303 | 2575 | } |
---|
2304 | 2576 | } |
---|
2305 | 2577 | } |
---|
| 2578 | + if (val == MODULE_STATE_GOING) |
---|
| 2579 | + remove_module_kprobe_blacklist(mod); |
---|
2306 | 2580 | mutex_unlock(&kprobe_mutex); |
---|
2307 | 2581 | return NOTIFY_DONE; |
---|
2308 | 2582 | } |
---|
.. | .. |
---|
2315 | 2589 | /* Markers of _kprobe_blacklist section */ |
---|
2316 | 2590 | extern unsigned long __start_kprobe_blacklist[]; |
---|
2317 | 2591 | extern unsigned long __stop_kprobe_blacklist[]; |
---|
| 2592 | + |
---|
| 2593 | +void kprobe_free_init_mem(void) |
---|
| 2594 | +{ |
---|
| 2595 | + void *start = (void *)(&__init_begin); |
---|
| 2596 | + void *end = (void *)(&__init_end); |
---|
| 2597 | + struct hlist_head *head; |
---|
| 2598 | + struct kprobe *p; |
---|
| 2599 | + int i; |
---|
| 2600 | + |
---|
| 2601 | + mutex_lock(&kprobe_mutex); |
---|
| 2602 | + |
---|
| 2603 | + /* Kill all kprobes on initmem */ |
---|
| 2604 | + for (i = 0; i < KPROBE_TABLE_SIZE; i++) { |
---|
| 2605 | + head = &kprobe_table[i]; |
---|
| 2606 | + hlist_for_each_entry(p, head, hlist) { |
---|
| 2607 | + if (start <= (void *)p->addr && (void *)p->addr < end) |
---|
| 2608 | + kill_kprobe(p); |
---|
| 2609 | + } |
---|
| 2610 | + } |
---|
| 2611 | + |
---|
| 2612 | + mutex_unlock(&kprobe_mutex); |
---|
| 2613 | +} |
---|
2318 | 2614 | |
---|
2319 | 2615 | static int __init init_kprobes(void) |
---|
2320 | 2616 | { |
---|
.. | .. |
---|
2346 | 2642 | } |
---|
2347 | 2643 | } |
---|
2348 | 2644 | |
---|
2349 | | -#if defined(CONFIG_OPTPROBES) |
---|
2350 | | -#if defined(__ARCH_WANT_KPROBES_INSN_SLOT) |
---|
2351 | | - /* Init kprobe_optinsn_slots */ |
---|
2352 | | - kprobe_optinsn_slots.insn_size = MAX_OPTINSN_SIZE; |
---|
2353 | | -#endif |
---|
2354 | | - /* By default, kprobes can be optimized */ |
---|
2355 | | - kprobes_allow_optimization = true; |
---|
2356 | | -#endif |
---|
2357 | | - |
---|
2358 | 2645 | /* By default, kprobes are armed */ |
---|
2359 | 2646 | kprobes_all_disarmed = false; |
---|
| 2647 | + |
---|
| 2648 | +#if defined(CONFIG_OPTPROBES) && defined(__ARCH_WANT_KPROBES_INSN_SLOT) |
---|
| 2649 | + /* Init kprobe_optinsn_slots for allocation */ |
---|
| 2650 | + kprobe_optinsn_slots.insn_size = MAX_OPTINSN_SIZE; |
---|
| 2651 | +#endif |
---|
2360 | 2652 | |
---|
2361 | 2653 | err = arch_init_kprobes(); |
---|
2362 | 2654 | if (!err) |
---|
.. | .. |
---|
2370 | 2662 | init_test_probes(); |
---|
2371 | 2663 | return err; |
---|
2372 | 2664 | } |
---|
| 2665 | +early_initcall(init_kprobes); |
---|
| 2666 | + |
---|
| 2667 | +#if defined(CONFIG_OPTPROBES) |
---|
| 2668 | +static int __init init_optprobes(void) |
---|
| 2669 | +{ |
---|
| 2670 | + /* |
---|
| 2671 | + * Enable kprobe optimization - this kicks the optimizer which |
---|
| 2672 | + * depends on synchronize_rcu_tasks() and ksoftirqd, that is |
---|
| 2673 | + * not spawned in early initcall. So delay the optimization. |
---|
| 2674 | + */ |
---|
| 2675 | + optimize_all_kprobes(); |
---|
| 2676 | + |
---|
| 2677 | + return 0; |
---|
| 2678 | +} |
---|
| 2679 | +subsys_initcall(init_optprobes); |
---|
| 2680 | +#endif |
---|
2373 | 2681 | |
---|
2374 | 2682 | #ifdef CONFIG_DEBUG_FS |
---|
2375 | 2683 | static void report_probe(struct seq_file *pi, struct kprobe *p, |
---|
.. | .. |
---|
2445 | 2753 | return 0; |
---|
2446 | 2754 | } |
---|
2447 | 2755 | |
---|
2448 | | -static const struct seq_operations kprobes_seq_ops = { |
---|
| 2756 | +static const struct seq_operations kprobes_sops = { |
---|
2449 | 2757 | .start = kprobe_seq_start, |
---|
2450 | 2758 | .next = kprobe_seq_next, |
---|
2451 | 2759 | .stop = kprobe_seq_stop, |
---|
2452 | 2760 | .show = show_kprobe_addr |
---|
2453 | 2761 | }; |
---|
2454 | 2762 | |
---|
2455 | | -static int kprobes_open(struct inode *inode, struct file *filp) |
---|
2456 | | -{ |
---|
2457 | | - return seq_open(filp, &kprobes_seq_ops); |
---|
2458 | | -} |
---|
2459 | | - |
---|
2460 | | -static const struct file_operations debugfs_kprobes_operations = { |
---|
2461 | | - .open = kprobes_open, |
---|
2462 | | - .read = seq_read, |
---|
2463 | | - .llseek = seq_lseek, |
---|
2464 | | - .release = seq_release, |
---|
2465 | | -}; |
---|
| 2763 | +DEFINE_SEQ_ATTRIBUTE(kprobes); |
---|
2466 | 2764 | |
---|
2467 | 2765 | /* kprobes/blacklist -- shows which functions can not be probed */ |
---|
2468 | 2766 | static void *kprobe_blacklist_seq_start(struct seq_file *m, loff_t *pos) |
---|
2469 | 2767 | { |
---|
| 2768 | + mutex_lock(&kprobe_mutex); |
---|
2470 | 2769 | return seq_list_start(&kprobe_blacklist, *pos); |
---|
2471 | 2770 | } |
---|
2472 | 2771 | |
---|
.. | .. |
---|
2493 | 2792 | return 0; |
---|
2494 | 2793 | } |
---|
2495 | 2794 | |
---|
2496 | | -static const struct seq_operations kprobe_blacklist_seq_ops = { |
---|
2497 | | - .start = kprobe_blacklist_seq_start, |
---|
2498 | | - .next = kprobe_blacklist_seq_next, |
---|
2499 | | - .stop = kprobe_seq_stop, /* Reuse void function */ |
---|
2500 | | - .show = kprobe_blacklist_seq_show, |
---|
2501 | | -}; |
---|
2502 | | - |
---|
2503 | | -static int kprobe_blacklist_open(struct inode *inode, struct file *filp) |
---|
| 2795 | +static void kprobe_blacklist_seq_stop(struct seq_file *f, void *v) |
---|
2504 | 2796 | { |
---|
2505 | | - return seq_open(filp, &kprobe_blacklist_seq_ops); |
---|
| 2797 | + mutex_unlock(&kprobe_mutex); |
---|
2506 | 2798 | } |
---|
2507 | 2799 | |
---|
2508 | | -static const struct file_operations debugfs_kprobe_blacklist_ops = { |
---|
2509 | | - .open = kprobe_blacklist_open, |
---|
2510 | | - .read = seq_read, |
---|
2511 | | - .llseek = seq_lseek, |
---|
2512 | | - .release = seq_release, |
---|
| 2800 | +static const struct seq_operations kprobe_blacklist_sops = { |
---|
| 2801 | + .start = kprobe_blacklist_seq_start, |
---|
| 2802 | + .next = kprobe_blacklist_seq_next, |
---|
| 2803 | + .stop = kprobe_blacklist_seq_stop, |
---|
| 2804 | + .show = kprobe_blacklist_seq_show, |
---|
2513 | 2805 | }; |
---|
| 2806 | +DEFINE_SEQ_ATTRIBUTE(kprobe_blacklist); |
---|
2514 | 2807 | |
---|
2515 | 2808 | static int arm_all_kprobes(void) |
---|
2516 | 2809 | { |
---|
.. | .. |
---|
2535 | 2828 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { |
---|
2536 | 2829 | head = &kprobe_table[i]; |
---|
2537 | 2830 | /* Arm all kprobes on a best-effort basis */ |
---|
2538 | | - hlist_for_each_entry_rcu(p, head, hlist) { |
---|
| 2831 | + hlist_for_each_entry(p, head, hlist) { |
---|
2539 | 2832 | if (!kprobe_disabled(p)) { |
---|
2540 | 2833 | err = arm_kprobe(p); |
---|
2541 | 2834 | if (err) { |
---|
.. | .. |
---|
2578 | 2871 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { |
---|
2579 | 2872 | head = &kprobe_table[i]; |
---|
2580 | 2873 | /* Disarm all kprobes on a best-effort basis */ |
---|
2581 | | - hlist_for_each_entry_rcu(p, head, hlist) { |
---|
| 2874 | + hlist_for_each_entry(p, head, hlist) { |
---|
2582 | 2875 | if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p)) { |
---|
2583 | 2876 | err = disarm_kprobe(p, false); |
---|
2584 | 2877 | if (err) { |
---|
.. | .. |
---|
2664 | 2957 | |
---|
2665 | 2958 | static int __init debugfs_kprobe_init(void) |
---|
2666 | 2959 | { |
---|
2667 | | - struct dentry *dir, *file; |
---|
2668 | | - unsigned int value = 1; |
---|
| 2960 | + struct dentry *dir; |
---|
2669 | 2961 | |
---|
2670 | 2962 | dir = debugfs_create_dir("kprobes", NULL); |
---|
2671 | | - if (!dir) |
---|
2672 | | - return -ENOMEM; |
---|
2673 | 2963 | |
---|
2674 | | - file = debugfs_create_file("list", 0400, dir, NULL, |
---|
2675 | | - &debugfs_kprobes_operations); |
---|
2676 | | - if (!file) |
---|
2677 | | - goto error; |
---|
| 2964 | + debugfs_create_file("list", 0400, dir, NULL, &kprobes_fops); |
---|
2678 | 2965 | |
---|
2679 | | - file = debugfs_create_file("enabled", 0600, dir, |
---|
2680 | | - &value, &fops_kp); |
---|
2681 | | - if (!file) |
---|
2682 | | - goto error; |
---|
| 2966 | + debugfs_create_file("enabled", 0600, dir, NULL, &fops_kp); |
---|
2683 | 2967 | |
---|
2684 | | - file = debugfs_create_file("blacklist", 0400, dir, NULL, |
---|
2685 | | - &debugfs_kprobe_blacklist_ops); |
---|
2686 | | - if (!file) |
---|
2687 | | - goto error; |
---|
| 2968 | + debugfs_create_file("blacklist", 0400, dir, NULL, |
---|
| 2969 | + &kprobe_blacklist_fops); |
---|
2688 | 2970 | |
---|
2689 | 2971 | return 0; |
---|
2690 | | - |
---|
2691 | | -error: |
---|
2692 | | - debugfs_remove(dir); |
---|
2693 | | - return -ENOMEM; |
---|
2694 | 2972 | } |
---|
2695 | 2973 | |
---|
2696 | 2974 | late_initcall(debugfs_kprobe_init); |
---|
2697 | 2975 | #endif /* CONFIG_DEBUG_FS */ |
---|
2698 | | - |
---|
2699 | | -module_init(init_kprobes); |
---|