lkml.org 
[lkml]   [2016]   [Jul]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 056/146] tracing: Handle NULL formats in hold_module_trace_bprintk_format()
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Steven Rostedt (Red Hat) <rostedt@goodmis.org>

    commit 70c8217acd4383e069fe1898bbad36ea4fcdbdcc upstream.

    If a task uses a non constant string for the format parameter in
    trace_printk(), then the trace_printk_fmt variable is set to NULL. This
    variable is then saved in the __trace_printk_fmt section.

    The function hold_module_trace_bprintk_format() checks to see if duplicate
    formats are used by modules, and reuses them if so (saves them to the list
    if it is new). But this function calls lookup_format() that does a strcmp()
    to the value (which is now NULL) and can cause a kernel oops.

    This wasn't an issue till 3debb0a9ddb ("tracing: Fix trace_printk() to print
    when not using bprintk()") which added "__used" to the trace_printk_fmt
    variable, and before that, the kernel simply optimized it out (no NULL value
    was saved).

    The fix is simply to handle the NULL pointer in lookup_format() and have the
    caller ignore the value if it was NULL.

    Link: http://lkml.kernel.org/r/1464769870-18344-1-git-send-email-zhengjun.xing@intel.com

    Reported-by: xingzhen <zhengjun.xing@intel.com>
    Acked-by: Namhyung Kim <namhyung@kernel.org>
    Fixes: 3debb0a9ddb ("tracing: Fix trace_printk() to print when not using bprintk()")
    Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    kernel/trace/trace_printk.c | 7 ++++++-
    1 file changed, 6 insertions(+), 1 deletion(-)

    --- a/kernel/trace/trace_printk.c
    +++ b/kernel/trace/trace_printk.c
    @@ -36,6 +36,10 @@ struct trace_bprintk_fmt {
    static inline struct trace_bprintk_fmt *lookup_format(const char *fmt)
    {
    struct trace_bprintk_fmt *pos;
    +
    + if (!fmt)
    + return ERR_PTR(-EINVAL);
    +
    list_for_each_entry(pos, &trace_bprintk_fmt_list, list) {
    if (!strcmp(pos->fmt, fmt))
    return pos;
    @@ -57,7 +61,8 @@ void hold_module_trace_bprintk_format(co
    for (iter = start; iter < end; iter++) {
    struct trace_bprintk_fmt *tb_fmt = lookup_format(*iter);
    if (tb_fmt) {
    - *iter = tb_fmt->fmt;
    + if (!IS_ERR(tb_fmt))
    + *iter = tb_fmt->fmt;
    continue;
    }


    \
     
     \ /
      Last update: 2016-07-26 01:21    [W:2.225 / U:2.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site