aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSong Liu <songliubraving@fb.com>2018-04-23 13:21:35 -0400
committerSteven Rostedt (VMware) <rostedt@goodmis.org>2018-04-26 14:50:56 -0400
commit61f94203c9efcaf44a7435298697caf406476c79 (patch)
tree28dbde5c548085dfae5eaef1484ef8e2b56db2d6
parent0c92c7a3c5d416f47b32c5f20a611dfeca5d5f2e (diff)
tracing: Remove igrab() iput() call from uprobes.c
Caller of uprobe_register is required to keep the inode and containing mount point referenced. There was misuse of igrab() in uprobes.c and trace_uprobe.c. This is because igrab() will not prevent umount of the containing mount point. To fix this, we added path to struct trace_uprobe, which keeps the inode and containing mount reference. For uprobes.c, it is not necessary to call igrab() in uprobe_register(), as the caller is required to keep the inode reference. The igrab() is removed and comments on this requirement is added to uprobe_register(). Link: http://lkml.kernel.org/r/CAELBmZB2XX=qEOLAdvGG4cPx4GEntcSnWQquJLUK1ongRj35cA@mail.gmail.com Link: http://lkml.kernel.org/r/20180423172135.4050588-2-songliubraving@fb.com Cc: Ingo Molnar <mingo@redhat.com> Cc: Howard McLauchlan <hmclauchlan@fb.com> Cc: Josef Bacik <jbacik@fb.com> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Acked-by: Miklos Szeredi <mszeredi@redhat.com> Signed-off-by: Song Liu <songliubraving@fb.com> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
-rw-r--r--kernel/events/uprobes.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index ce6848e46e94..1725b902983f 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -491,7 +491,7 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
491 if (!uprobe) 491 if (!uprobe)
492 return NULL; 492 return NULL;
493 493
494 uprobe->inode = igrab(inode); 494 uprobe->inode = inode;
495 uprobe->offset = offset; 495 uprobe->offset = offset;
496 init_rwsem(&uprobe->register_rwsem); 496 init_rwsem(&uprobe->register_rwsem);
497 init_rwsem(&uprobe->consumer_rwsem); 497 init_rwsem(&uprobe->consumer_rwsem);
@@ -502,7 +502,6 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
502 if (cur_uprobe) { 502 if (cur_uprobe) {
503 kfree(uprobe); 503 kfree(uprobe);
504 uprobe = cur_uprobe; 504 uprobe = cur_uprobe;
505 iput(inode);
506 } 505 }
507 506
508 return uprobe; 507 return uprobe;
@@ -701,7 +700,6 @@ static void delete_uprobe(struct uprobe *uprobe)
701 rb_erase(&uprobe->rb_node, &uprobes_tree); 700 rb_erase(&uprobe->rb_node, &uprobes_tree);
702 spin_unlock(&uprobes_treelock); 701 spin_unlock(&uprobes_treelock);
703 RB_CLEAR_NODE(&uprobe->rb_node); /* for uprobe_is_active() */ 702 RB_CLEAR_NODE(&uprobe->rb_node); /* for uprobe_is_active() */
704 iput(uprobe->inode);
705 put_uprobe(uprobe); 703 put_uprobe(uprobe);
706} 704}
707 705
@@ -873,7 +871,8 @@ static void __uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *u
873 * tuple). Creation refcount stops uprobe_unregister from freeing the 871 * tuple). Creation refcount stops uprobe_unregister from freeing the
874 * @uprobe even before the register operation is complete. Creation 872 * @uprobe even before the register operation is complete. Creation
875 * refcount is released when the last @uc for the @uprobe 873 * refcount is released when the last @uc for the @uprobe
876 * unregisters. 874 * unregisters. Caller of uprobe_register() is required to keep @inode
875 * (and the containing mount) referenced.
877 * 876 *
878 * Return errno if it cannot successully install probes 877 * Return errno if it cannot successully install probes
879 * else return 0 (success) 878 * else return 0 (success)