Skip to content
  • Steven Rostedt (VMware)'s avatar
    vsprintf: Do not have bprintf dereference pointers · 841a915d
    Steven Rostedt (VMware) authored
    When trace_printk() was introduced, it was discussed that making it be as
    low overhead as possible, that the processing of the format string should be
    delayed until it is read. That is, a "trace_printk()" should not convert
    the %d into numbers and so on, but instead, save the fmt string and all the
    args in the buffer at the time of recording. When the trace_printk() data is
    read, it would then parse the format string and do the conversions of the
    saved arguments in the tracing buffer.
    
    The code to perform this was added to vsprintf where vbin_printf() would
    save the arguments of a specified format string in a buffer, then
    bstr_printf() could be used to convert the buffer with the same format
    string into the final output, as if vsprintf() was called in one go.
    
    The issue arises when dereferenced pointers are used. The problem is that
    something like %*pbl which reads a bitmask, will save the pointer to the
    bitmask in the buffer. Then the reading of the buffer via bstr_printf() will
    then look at the pointer to process the final output. Obviously the value of
    that pointer could have changed since the time it was recorded to the time
    the buffer is read. Worse yet, the bitmask could be unmapped, and the
    reading of the trace buffer could actually cause a kernel oops.
    
    Another problem is that user space tools such as perf and trace-cmd do not
    have access to the contents of these pointers, and they become useless when
    the tracing buffer is extracted.
    
    Instead of having vbin_printf() simply save the pointer in the buffer for
    later processing, have it perform the formatting at the time bin_printf() is
    called. This will fix the issue of dereferencing pointers at a later time,
    and has the extra benefit of having user space tools understand these
    values.
    
    Since perf and trace-cmd already can handle %p[sSfF] via saving kallsyms,
    their pointers are saved and not processed during vbin_printf(). If they
    were converted, it would break perf and trace-cmd, as they would not know
    how to deal with the conversion.
    
    Link: http://lkml.kernel.org/r/20171228204025.14a71d8f@gandalf.local.home
    
    
    
    Reported-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
    841a915d