Skip to content

Commit 64db338

Browse files
rostedtgregkh
authored andcommitted
ftrace: Also allocate and copy hash for reading of filter files
commit bfb336c upstream. Currently the reader of set_ftrace_filter and set_ftrace_notrace just adds the pointer to the global tracer hash to its iterator. Unlike the writer that allocates a copy of the hash, the reader keeps the pointer to the filter hashes. This is problematic because this pointer is static across function calls that release the locks that can update the global tracer hashes. This can cause UAF and similar bugs. Allocate and copy the hash for reading the filter files like it is done for the writers. This not only fixes UAF bugs, but also makes the code a bit simpler as it doesn't have to differentiate when to free the iterator's hash between writers and readers. Cc: stable@vger.kernel.org Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Nathan Chancellor <nathan@kernel.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Link: https://lore.kernel.org/20250822183606.12962cc3@batman.local.home Fixes: c20489d ("ftrace: Assign iter->hash to filter or notrace hashes on seq read") Closes: https://lore.kernel.org/all/20250813023044.2121943-1-wutengda@huaweicloud.com/ Closes: https://lore.kernel.org/all/20250822192437.GA458494@ax162/ Reported-by: Tengda Wu <wutengda@huaweicloud.com> Tested-by: Tengda Wu <wutengda@huaweicloud.com> Tested-by: Nathan Chancellor <nathan@kernel.org> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent c88c04a commit 64db338

File tree

1 file changed

+10
-9
lines changed

1 file changed

+10
-9
lines changed

kernel/trace/ftrace.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4665,13 +4665,17 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
46654665
} else {
46664666
iter->hash = alloc_and_copy_ftrace_hash(size_bits, hash);
46674667
}
4668+
} else {
4669+
if (hash)
4670+
iter->hash = alloc_and_copy_ftrace_hash(hash->size_bits, hash);
4671+
else
4672+
iter->hash = EMPTY_HASH;
4673+
}
46684674

4669-
if (!iter->hash) {
4670-
trace_parser_put(&iter->parser);
4671-
goto out_unlock;
4672-
}
4673-
} else
4674-
iter->hash = hash;
4675+
if (!iter->hash) {
4676+
trace_parser_put(&iter->parser);
4677+
goto out_unlock;
4678+
}
46754679

46764680
ret = 0;
46774681

@@ -6547,9 +6551,6 @@ int ftrace_regex_release(struct inode *inode, struct file *file)
65476551
ftrace_hash_move_and_update_ops(iter->ops, orig_hash,
65486552
iter->hash, filter_hash);
65496553
mutex_unlock(&ftrace_lock);
6550-
} else {
6551-
/* For read only, the hash is the ops hash */
6552-
iter->hash = NULL;
65536554
}
65546555

65556556
mutex_unlock(&iter->ops->func_hash->regex_lock);

0 commit comments

Comments
 (0)