• Oleg Nesterov's avatar
    tracing: Introduce trace_create_cpu_file() and tracing_get_cpu() · 649e9c70
    Oleg Nesterov authored
    Every "file_operations" used by tracing_init_debugfs_percpu is buggy.
    f_op->open/etc does:
    	1. struct trace_cpu *tc = inode->i_private;
    	   struct trace_array *tr = tc->tr;
    	2. trace_array_get(tr) or fail;
    	3. do_something(tc);
    But tc (and tr) can be already freed before trace_array_get() is called.
    And it doesn't matter whether this file is per-cpu or it was created by
    init_tracer_debugfs(), free_percpu() or kfree() are equally bad.
    Note that even 1. is not safe, the freed memory can be unmapped. But even
    if it was safe trace_array_get() can wrongly succeed if we also race with
    the next new_instance_create() which can re-allocate the same tr, or tc
    was overwritten and ->tr points to the valid tr. In this case 3. uses the
    freed/reused memory.
    Add the new trivial helper, trace_create_cpu_file() which simply calls
    trace_create_file() and encodes "cpu" in "struct inode". Another helper,
    tracing_get_cpu() will be used to read cpu_nr-or-RING_BUFFER_ALL_CPUS.
    The patch abuses ->i_cdev to encode the number, it is never used unless
    the file is S_ISCHR(). But we could use something else, say, i_bytes or
    even ->d_fsdata. In any case this hack is hidden inside these 2 helpers,
    it would be trivial to change them if needed.
    This patch only changes tracing_init_debugfs_percpu() to use the new
    trace_create_cpu_file(), the next patches will change file_operations.
    Note: tracing_get_cpu(inode) is always safe but you can't trust the
    result unless trace_array_get() was called, without trace_types_lock
    which acts as a barrier it can wrongly return RING_BUFFER_ALL_CPUS.
    Link: http://lkml.kernel.org/r/20130723152554.GA23710@redhat.com
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: default avatarOleg Nesterov <oleg@redhat.com>
    Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
trace.c 154 KB