Remove race condition from __swap_unregister_uprobe() 89/99689/1
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Wed, 23 Nov 2016 16:13:05 +0000 (19:13 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Wed, 23 Nov 2016 16:13:05 +0000 (19:13 +0300)
Add rcu_read_lock() for RCU-lists traversal.

Change-Id: Ifd35cb42222bef7f00b64da3db23a65dcf2e3c93
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
uprobe/swap_uprobes.c

index cee4adc..dfe6523 100644 (file)
@@ -550,17 +550,22 @@ void __swap_unregister_uprobe(struct uprobe *p, int disarm)
        if (!p->task)
                return;
 
+       rcu_read_lock();
        old_p = get_uprobe(p->addr, p->task->tgid);
+       rcu_read_unlock();
        if (unlikely(!old_p))
                return;
 
        if (p != old_p) {
+               rcu_read_lock();
                list_for_each_entry_rcu(list_p, &old_p->list, list) {
                        if (list_p == p) {
                                /* uprobe p is a valid probe */
+                               rcu_read_unlock();
                                goto valid_p;
                        }
                }
+               rcu_read_unlock();
 
                return;
        }
@@ -598,12 +603,14 @@ valid_p:
                        old_p->break_handler = NULL;
 
                if (p->post_handler) {
+                       rcu_read_lock();
                        list_for_each_entry_rcu(list_p, &old_p->list, list) {
                                if (list_p->post_handler) {
                                        cleanup_p = 2;
                                        break;
                                }
                        }
+                       rcu_read_unlock();
 
                        if (cleanup_p == 0)
                                old_p->post_handler = NULL;