• Steven Rostedt (Red Hat)'s avatar
    ring-buffer: Up rb_iter_peek() loop count to 3 · 39ed6dfc
    Steven Rostedt (Red Hat) authored
    commit 021de3d9 upstream.
    
    After writting a test to try to trigger the bug that caused the
    ring buffer iterator to become corrupted, I hit another bug:
    
     WARNING: CPU: 1 PID: 5281 at kernel/trace/ring_buffer.c:3766 rb_iter_peek+0x113/0x238()
     Modules linked in: ipt_MASQUERADE sunrpc [...]
     CPU: 1 PID: 5281 Comm: grep Tainted: G        W     3.16.0-rc3-test+ #143
     Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./To be filled by O.E.M., BIOS SDBLI944.86P 05/08/2007
      0000000000000000 ffffffff81809a80 ffffffff81503fb0 0000000000000000
      ffffffff81040ca1 ffff8800796d6010 ffffffff810c138d ffff8800796d6010
      ffff880077438c80 ffff8800796d6010 ffff88007abbe600 0000000000000003
     Call Trace:
      [<ffffffff81503fb0>] ? dump_stack+0x4a/0x75
      [<ffffffff81040ca1>] ? warn_slowpath_common+0x7e/0x97
      [<ffffffff810c138d>] ? rb_iter_peek+0x113/0x238
      [<ffffffff810c138d>] ? rb_iter_peek+0x113/0x238
      [<ffffffff810c14df>] ? ring_buffer_iter_peek+0x2d/0x5c
      [<ffffffff810c6f73>] ? tracing_iter_reset+0x6e/0x96
      [<ffffffff810c74a3>] ? s_start+0xd7/0x17b
      [<ffffffff8112b13e>] ? kmem_cache_alloc_trace+0xda/0xea
      [<ffffffff8114cf94>] ? seq_read+0x148/0x361
      [<ffffffff81132d98>] ? vfs_read+0x93/0xf1
      [<ffffffff81132f1b>] ? SyS_read+0x60/0x8e
      [<ffffffff8150bf9f>] ? tracesys+0xdd/0xe2
    
    Debugging this bug, which triggers when the rb_iter_peek() loops too
    many times (more than 2 times), I discovered there's a case that can
    cause that function to legitimately loop 3 times!
    
    rb_iter_peek() is different than rb_buffer_peek() as the rb_buffer_peek()
    only deals with the reader page (it's for consuming reads). The
    rb_iter_peek() is for traversing the buffer without consuming it, and as
    such, it can loop for one more reason. That is, if we hit the end of
    the reader page or any page, it will go to the next page and try again.
    
    That is, we have this:
    
     1. iter->head > iter->head_page->page->commit
        (rb_inc_iter() which moves the iter to the next page)
        try again
    
     2. event = rb_iter_head_event()
        event->type_len == RINGBUF_TYPE_TIME_EXTEND
        rb_advance_iter()
        try again
    
     3. read the event.
    
    But we never get to 3, because the count is greater than 2 and we
    cause the WARNING and return NULL.
    
    Up the counter to 3.
    
    Fixes: 69d1b839 "ring-buffer: Bind time extend and data events together"
    Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    39ed6dfc
ring_buffer.c 129 KB