ftrace: Check for empty hash and comment the race with registering probes [Linux 4.19.70]

This Linux kernel change "ftrace: Check for empty hash and comment the race with registering probes" is included in the Linux 4.19.70 release. This change is authored by Steven Rostedt (VMware) <rostedt [at] goodmis.org> on Fri Aug 30 16:30:01 2019 -0400. The commit for this change in Linux stable tree is 8ea6395 (patch) which is from upstream commit 372e0d0. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 372e0d0.

ftrace: Check for empty hash and comment the race with registering probes

commit 372e0d01da71c84dcecf7028598a33813b0d5256 upstream.

The race between adding a function probe and reading the probes that exist
is very subtle. It needs a comment. Also, the issue can also happen if the
probe has has the EMPTY_HASH as its func_hash.

Cc: stable@vger.kernel.org
Fixes: 7b60f3d876156 ("ftrace: Dynamically create the probe ftrace_ops for the trace_array")
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

There are 10 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 kernel/trace/ftrace.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index fada893..7e215da 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3113,7 +3113,11 @@ struct ftrace_iterator {

    hash = iter->probe->ops.func_hash->filter_hash;

-   if (!hash)
+   /*
+    * A probe being registered may temporarily have an empty hash
+    * and it's at the end of the func_probes list.
+    */
+   if (!hash || hash == EMPTY_HASH)
        return NULL;

    size = 1 << hash->size_bits;
@@ -4311,6 +4315,10 @@ static void acquire_probe_locked(struct ftrace_func_probe *probe)

    mutex_unlock(&ftrace_lock);

+   /*
+    * Note, there's a small window here that the func_hash->filter_hash
+    * may be NULL or empty. Need to be carefule when reading the loop.
+    */
    mutex_lock(&probe->ops.func_hash->regex_lock);

    orig_hash = &probe->ops.func_hash->filter_hash;

Leave a Reply

Your email address will not be published. Required fields are marked *