Skip to content
  • Dmitry Vyukov's avatar
    lib/llist.c: fix data race in llist_del_first · 2cf12f82
    Dmitry Vyukov authored
    llist_del_first reads entry->next, but it did not acquire visibility over
    the entry node.  As the result it can get a stale value of entry->next
    (e.g.  NULL or whatever garbage was there before the appending thread
    wrote correct value).  And then commit that value as llist head with
    cmpxchg.  That will corrupt llist.
    
    Note there is a control-dependency between read of head->first and read of
    entry->next, but it does not make the code correct.  Kernel memory model
    unambiguously says: "A load-load control dependency requires a full read
    memory barrier".
    
    Use smp_load_acquire to acquire visibility over the entry node.
    
    The data race was found with KernelThreadSanitizer (KTSAN).
    
    Here is an example of KTSAN report:
    
    ThreadSanitizer: data-race in llist_del_first
    
    Read of size 1 by thread T389 (K2630, CPU0):
     [<ffffffff8156b8a9>] llist_del_first+0x39/0x70 lib/llist.c:74
     [<     inlined    >] tty_buffer_alloc drivers/tty/tty_buffer.c:181
     [<ffffffff81664af4>] __tty_b...
    2cf12f82