)]}'
{
  "commit": "85f4f12d51397f1648e1f4350f77e24039b82d61",
  "tree": "7913a89f385849f276a99c2fbfa2a1e345d3ddbd",
  "parents": [
    "67b8d5c7081221efa252e111cd52532ec6d4266f"
  ],
  "author": {
    "name": "Steven Rostedt (VMware)",
    "email": "rostedt@goodmis.org",
    "time": "Tue May 15 22:24:52 2018 -0400"
  },
  "committer": {
    "name": "Steven Rostedt (VMware)",
    "email": "rostedt@goodmis.org",
    "time": "Wed May 16 09:01:41 2018 -0400"
  },
  "message": "vsprintf: Replace memory barrier with static_key for random_ptr_key update\n\nReviewing Tobin\u0027s patches for getting pointers out early before\nentropy has been established, I noticed that there\u0027s a lone smp_mb() in\nthe code. As with most lone memory barriers, this one appears to be\nincorrectly used.\n\nWe currently basically have this:\n\n\tget_random_bytes(\u0026ptr_key, sizeof(ptr_key));\n\t/*\n\t * have_filled_random_ptr_key\u003d\u003dtrue is dependent on get_random_bytes().\n\t * ptr_to_id() needs to see have_filled_random_ptr_key\u003d\u003dtrue\n\t * after get_random_bytes() returns.\n\t */\n\tsmp_mb();\n\tWRITE_ONCE(have_filled_random_ptr_key, true);\n\nAnd later we have:\n\n\tif (unlikely(!have_filled_random_ptr_key))\n\t\treturn string(buf, end, \"(ptrval)\", spec);\n\n/* Missing memory barrier here. */\n\n\thashval \u003d (unsigned long)siphash_1u64((u64)ptr, \u0026ptr_key);\n\nAs the CPU can perform speculative loads, we could have a situation\nwith the following:\n\n\tCPU0\t\t\t\tCPU1\n\t----\t\t\t\t----\n\t\t\t\t   load ptr_key \u003d 0\n   store ptr_key \u003d random\n   smp_mb()\n   store have_filled_random_ptr_key\n\n\t\t\t\t   load have_filled_random_ptr_key \u003d true\n\n\t\t\t\t    BAD BAD BAD! (you\u0027re so bad!)\n\nBecause nothing prevents CPU1 from loading ptr_key before loading\nhave_filled_random_ptr_key.\n\nBut this race is very unlikely, but we can\u0027t keep an incorrect smp_mb() in\nplace. Instead, replace the have_filled_random_ptr_key with a static_branch\nnot_filled_random_ptr_key, that is initialized to true and changed to false\nwhen we get enough entropy. If the update happens in early boot, the\nstatic_key is updated immediately, otherwise it will have to wait till\nentropy is filled and this happens in an interrupt handler which can\u0027t\nenable a static_key, as that requires a preemptible context. In that case, a\nwork_queue is used to enable it, as entropy already took too long to\nestablish in the first place waiting a little more shouldn\u0027t hurt anything.\n\nThe benefit of using the static key is that the unlikely branch in\nvsprintf() now becomes a nop.\n\nLink: http://lkml.kernel.org/r/20180515100558.21df515e@gandalf.local.home\n\nCc: stable@vger.kernel.org\nFixes: ad67b74d2469d (\"printk: hash addresses printed with %p\")\nAcked-by: Linus Torvalds \u003ctorvalds@linux-foundation.org\u003e\nSigned-off-by: Steven Rostedt (VMware) \u003crostedt@goodmis.org\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "30c0cb8cc9bce78089cb6ad48bcb6b3d5d02e6b2",
      "old_mode": 33188,
      "old_path": "lib/vsprintf.c",
      "new_id": "23920c5ff72859c79f4f50e8e267b56c8f230c7c",
      "new_mode": 33188,
      "new_path": "lib/vsprintf.c"
    }
  ]
}
