diff options
author | Song Liu <songliubraving@fb.com> | 2018-04-23 13:21:35 -0400 |
---|---|---|
committer | Steven Rostedt (VMware) <rostedt@goodmis.org> | 2018-04-26 14:50:56 -0400 |
commit | 61f94203c9efcaf44a7435298697caf406476c79 (patch) | |
tree | 28dbde5c548085dfae5eaef1484ef8e2b56db2d6 | |
parent | 0c92c7a3c5d416f47b32c5f20a611dfeca5d5f2e (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.c | 7 |
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) |