aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/kprobes.c93
1 files changed, 46 insertions, 47 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 9737a76e106f..8c3aa1452201 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -357,10 +357,10 @@ static inline int kprobe_aggrprobe(struct kprobe *p)
357/* 357/*
358 * Keep all fields in the kprobe consistent 358 * Keep all fields in the kprobe consistent
359 */ 359 */
360static inline void copy_kprobe(struct kprobe *old_p, struct kprobe *p) 360static inline void copy_kprobe(struct kprobe *ap, struct kprobe *p)
361{ 361{
362 memcpy(&p->opcode, &old_p->opcode, sizeof(kprobe_opcode_t)); 362 memcpy(&p->opcode, &ap->opcode, sizeof(kprobe_opcode_t));
363 memcpy(&p->ainsn, &old_p->ainsn, sizeof(struct arch_specific_insn)); 363 memcpy(&p->ainsn, &ap->ainsn, sizeof(struct arch_specific_insn));
364} 364}
365 365
366#ifdef CONFIG_OPTPROBES 366#ifdef CONFIG_OPTPROBES
@@ -671,12 +671,12 @@ int proc_kprobes_optimization_handler(struct ctl_table *table, int write,
671 671
672static void __kprobes __arm_kprobe(struct kprobe *p) 672static void __kprobes __arm_kprobe(struct kprobe *p)
673{ 673{
674 struct kprobe *old_p; 674 struct kprobe *_p;
675 675
676 /* Check collision with other optimized kprobes */ 676 /* Check collision with other optimized kprobes */
677 old_p = get_optimized_kprobe((unsigned long)p->addr); 677 _p = get_optimized_kprobe((unsigned long)p->addr);
678 if (unlikely(old_p)) 678 if (unlikely(_p))
679 unoptimize_kprobe(old_p); /* Fallback to unoptimized kprobe */ 679 unoptimize_kprobe(_p); /* Fallback to unoptimized kprobe */
680 680
681 arch_arm_kprobe(p); 681 arch_arm_kprobe(p);
682 optimize_kprobe(p); /* Try to optimize (add kprobe to a list) */ 682 optimize_kprobe(p); /* Try to optimize (add kprobe to a list) */
@@ -684,15 +684,15 @@ static void __kprobes __arm_kprobe(struct kprobe *p)
684 684
685static void __kprobes __disarm_kprobe(struct kprobe *p) 685static void __kprobes __disarm_kprobe(struct kprobe *p)
686{ 686{
687 struct kprobe *old_p; 687 struct kprobe *_p;
688 688
689 unoptimize_kprobe(p); /* Try to unoptimize */ 689 unoptimize_kprobe(p); /* Try to unoptimize */
690 arch_disarm_kprobe(p); 690 arch_disarm_kprobe(p);
691 691
692 /* If another kprobe was blocked, optimize it. */ 692 /* If another kprobe was blocked, optimize it. */
693 old_p = get_optimized_kprobe((unsigned long)p->addr); 693 _p = get_optimized_kprobe((unsigned long)p->addr);
694 if (unlikely(old_p)) 694 if (unlikely(_p))
695 optimize_kprobe(old_p); 695 optimize_kprobe(_p);
696} 696}
697 697
698#else /* !CONFIG_OPTPROBES */ 698#else /* !CONFIG_OPTPROBES */
@@ -993,18 +993,18 @@ static void __kprobes init_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
993 * This is the second or subsequent kprobe at the address - handle 993 * This is the second or subsequent kprobe at the address - handle
994 * the intricacies 994 * the intricacies
995 */ 995 */
996static int __kprobes register_aggr_kprobe(struct kprobe *old_p, 996static int __kprobes register_aggr_kprobe(struct kprobe *orig_p,
997 struct kprobe *p) 997 struct kprobe *p)
998{ 998{
999 int ret = 0; 999 int ret = 0;
1000 struct kprobe *ap = old_p; 1000 struct kprobe *ap = orig_p;
1001 1001
1002 if (!kprobe_aggrprobe(old_p)) { 1002 if (!kprobe_aggrprobe(orig_p)) {
1003 /* If old_p is not an aggr_kprobe, create new aggr_kprobe. */ 1003 /* If orig_p is not an aggr_kprobe, create new aggr_kprobe. */
1004 ap = alloc_aggr_kprobe(old_p); 1004 ap = alloc_aggr_kprobe(orig_p);
1005 if (!ap) 1005 if (!ap)
1006 return -ENOMEM; 1006 return -ENOMEM;
1007 init_aggr_kprobe(ap, old_p); 1007 init_aggr_kprobe(ap, orig_p);
1008 } 1008 }
1009 1009
1010 if (kprobe_gone(ap)) { 1010 if (kprobe_gone(ap)) {
@@ -1098,34 +1098,33 @@ static kprobe_opcode_t __kprobes *kprobe_addr(struct kprobe *p)
1098/* Check passed kprobe is valid and return kprobe in kprobe_table. */ 1098/* Check passed kprobe is valid and return kprobe in kprobe_table. */
1099static struct kprobe * __kprobes __get_valid_kprobe(struct kprobe *p) 1099static struct kprobe * __kprobes __get_valid_kprobe(struct kprobe *p)
1100{ 1100{
1101 struct kprobe *old_p, *list_p; 1101 struct kprobe *ap, *list_p;
1102 1102
1103 old_p = get_kprobe(p->addr); 1103 ap = get_kprobe(p->addr);
1104 if (unlikely(!old_p)) 1104 if (unlikely(!ap))
1105 return NULL; 1105 return NULL;
1106 1106
1107 if (p != old_p) { 1107 if (p != ap) {
1108 list_for_each_entry_rcu(list_p, &old_p->list, list) 1108 list_for_each_entry_rcu(list_p, &ap->list, list)
1109 if (list_p == p) 1109 if (list_p == p)
1110 /* kprobe p is a valid probe */ 1110 /* kprobe p is a valid probe */
1111 goto valid; 1111 goto valid;
1112 return NULL; 1112 return NULL;
1113 } 1113 }
1114valid: 1114valid:
1115 return old_p; 1115 return ap;
1116} 1116}
1117 1117
1118/* Return error if the kprobe is being re-registered */ 1118/* Return error if the kprobe is being re-registered */
1119static inline int check_kprobe_rereg(struct kprobe *p) 1119static inline int check_kprobe_rereg(struct kprobe *p)
1120{ 1120{
1121 int ret = 0; 1121 int ret = 0;
1122 struct kprobe *old_p;
1123 1122
1124 mutex_lock(&kprobe_mutex); 1123 mutex_lock(&kprobe_mutex);
1125 old_p = __get_valid_kprobe(p); 1124 if (__get_valid_kprobe(p))
1126 if (old_p)
1127 ret = -EINVAL; 1125 ret = -EINVAL;
1128 mutex_unlock(&kprobe_mutex); 1126 mutex_unlock(&kprobe_mutex);
1127
1129 return ret; 1128 return ret;
1130} 1129}
1131 1130
@@ -1234,43 +1233,43 @@ EXPORT_SYMBOL_GPL(register_kprobe);
1234 */ 1233 */
1235static int __kprobes __unregister_kprobe_top(struct kprobe *p) 1234static int __kprobes __unregister_kprobe_top(struct kprobe *p)
1236{ 1235{
1237 struct kprobe *old_p, *list_p; 1236 struct kprobe *ap, *list_p;
1238 1237
1239 old_p = __get_valid_kprobe(p); 1238 ap = __get_valid_kprobe(p);
1240 if (old_p == NULL) 1239 if (ap == NULL)
1241 return -EINVAL; 1240 return -EINVAL;
1242 1241
1243 if (old_p == p || 1242 if (ap == p ||
1244 (kprobe_aggrprobe(old_p) && 1243 (kprobe_aggrprobe(ap) &&
1245 list_is_singular(&old_p->list))) { 1244 list_is_singular(&ap->list))) {
1246 /* 1245 /*
1247 * Only probe on the hash list. Disarm only if kprobes are 1246 * Only probe on the hash list. Disarm only if kprobes are
1248 * enabled and not gone - otherwise, the breakpoint would 1247 * enabled and not gone - otherwise, the breakpoint would
1249 * already have been removed. We save on flushing icache. 1248 * already have been removed. We save on flushing icache.
1250 */ 1249 */
1251 if (!kprobes_all_disarmed && !kprobe_disabled(old_p)) 1250 if (!kprobes_all_disarmed && !kprobe_disabled(ap))
1252 disarm_kprobe(old_p); 1251 disarm_kprobe(ap);
1253 hlist_del_rcu(&old_p->hlist); 1252 hlist_del_rcu(&ap->hlist);
1254 } else { 1253 } else {
1255 if (p->break_handler && !kprobe_gone(p)) 1254 if (p->break_handler && !kprobe_gone(p))
1256 old_p->break_handler = NULL; 1255 ap->break_handler = NULL;
1257 if (p->post_handler && !kprobe_gone(p)) { 1256 if (p->post_handler && !kprobe_gone(p)) {
1258 list_for_each_entry_rcu(list_p, &old_p->list, list) { 1257 list_for_each_entry_rcu(list_p, &ap->list, list) {
1259 if ((list_p != p) && (list_p->post_handler)) 1258 if ((list_p != p) && (list_p->post_handler))
1260 goto noclean; 1259 goto noclean;
1261 } 1260 }
1262 old_p->post_handler = NULL; 1261 ap->post_handler = NULL;
1263 } 1262 }
1264noclean: 1263noclean:
1265 list_del_rcu(&p->list); 1264 list_del_rcu(&p->list);
1266 if (!kprobe_disabled(old_p)) { 1265 if (!kprobe_disabled(ap)) {
1267 try_to_disable_aggr_kprobe(old_p); 1266 try_to_disable_aggr_kprobe(ap);
1268 if (!kprobes_all_disarmed) { 1267 if (!kprobes_all_disarmed) {
1269 if (kprobe_disabled(old_p)) 1268 if (kprobe_disabled(ap))
1270 disarm_kprobe(old_p); 1269 disarm_kprobe(ap);
1271 else 1270 else
1272 /* Try to optimize this probe again */ 1271 /* Try to optimize this probe again */
1273 optimize_kprobe(old_p); 1272 optimize_kprobe(ap);
1274 } 1273 }
1275 } 1274 }
1276 } 1275 }
@@ -1279,16 +1278,16 @@ noclean:
1279 1278
1280static void __kprobes __unregister_kprobe_bottom(struct kprobe *p) 1279static void __kprobes __unregister_kprobe_bottom(struct kprobe *p)
1281{ 1280{
1282 struct kprobe *old_p; 1281 struct kprobe *ap;
1283 1282
1284 if (list_empty(&p->list)) 1283 if (list_empty(&p->list))
1285 arch_remove_kprobe(p); 1284 arch_remove_kprobe(p);
1286 else if (list_is_singular(&p->list)) { 1285 else if (list_is_singular(&p->list)) {
1287 /* "p" is the last child of an aggr_kprobe */ 1286 /* "p" is the last child of an aggr_kprobe */
1288 old_p = list_entry(p->list.next, struct kprobe, list); 1287 ap = list_entry(p->list.next, struct kprobe, list);
1289 list_del(&p->list); 1288 list_del(&p->list);
1290 arch_remove_kprobe(old_p); 1289 arch_remove_kprobe(ap);
1291 free_aggr_kprobe(old_p); 1290 free_aggr_kprobe(ap);
1292 } 1291 }
1293} 1292}
1294 1293