1. 21 Mar, 2013 23 commits
  2. 20 Mar, 2013 7 commits
  3. 18 Mar, 2013 3 commits
  4. 15 Mar, 2013 5 commits
  5. 14 Mar, 2013 2 commits
    • Linus Torvalds's avatar
      Merge branch 'rcu/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu · f4846e52
      Linus Torvalds authored
      Pull fix for hlist_entry_safe() regression from Paul McKenney:
       "This contains a single commit that fixes a regression in
        hlist_entry_safe().  This macro references its argument twice, which
        can cause NULL-pointer errors.  This commit applies a gcc statement
        expression, creating a temporary variable to avoid the double
        reference.  This has been posted to LKML at
      
          https://lkml.org/lkml/2013/3/9/75.
      
        Kudos to CAI Qian, whose testing uncovered this, to Eric Dumazet, who
        spotted root cause, and to Li Zefan, who tested this commit."
      
      * 'rcu/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu:
        list: Fix double fetch of pointer in hlist_entry_safe()
      f4846e52
    • Paul E. McKenney's avatar
      list: Fix double fetch of pointer in hlist_entry_safe() · f65846a1
      Paul E. McKenney authored
      The current version of hlist_entry_safe() fetches the pointer twice,
      once to test for NULL and the other to compute the offset back to the
      enclosing structure.  This is OK for normal lock-based use because in
      that case, the pointer cannot change.  However, when the pointer is
      protected by RCU (as in "rcu_dereference(p)"), then the pointer can
      change at any time.  This use case can result in the following sequence
      of events:
      
      1.	CPU 0 invokes hlist_entry_safe(), fetches the RCU-protected
      	pointer as sees that it is non-NULL.
      
      2.	CPU 1 invokes hlist_del_rcu(), deleting the entry that CPU 0
      	just fetched a pointer to.  Because this is the last entry
      	in the list, the pointer fetched by CPU 0 is now NULL.
      
      3.	CPU 0 refetches the pointer, obtains NULL, and then gets a
      	NULL-pointer crash.
      
      This commit therefore applies gcc's "({ })" statement expression to
      create a temporary variable so that the specified pointer is fetched
      only once, avoiding the above sequence of events.  Please note that
      it is the caller's responsibility to use rcu_dereference() as needed.
      This allows RCU-protected uses to work correctly without imposing
      any additional overhead on the non-RCU case.
      
      Many thanks to Eric Dumazet for spotting root cause!
      Reported-by: default avatarCAI Qian <caiqian@redhat.com>
      Reported-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
      Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
      Tested-by: default avatarLi Zefan <lizefan@huawei.com>
      f65846a1