)]}'
{
  "commit": "7fcd59b64a7b69718cc851865a1578138b481541",
  "tree": "ea426d03331442a3c7ab1aaf67c8b0eb029c5451",
  "parents": [
    "6aa32af801023cd8a2112937385e6d6bca6f858e"
  ],
  "author": {
    "name": "Al Viro",
    "email": "viro@zeniv.linux.org.uk",
    "time": "Tue Nov 12 16:13:06 2019 -0500"
  },
  "committer": {
    "name": "Al Viro",
    "email": "viro@zeniv.linux.org.uk",
    "time": "Thu Dec 05 21:04:35 2019 -0500"
  },
  "message": "fs/namei.c: fix missing barriers when checking positivity\n\nPinned negative dentries can, generally, be made positive\nby another thread.  Conditions that prevent that are\n\t* -\u003ed_lock on dentry in question\n\t* parent directory held at least shared\n\t* nobody else could have observed the address of dentry\nMost of the places working with those fall into one of those\ncategories; however, d_lookup() and friends need to be used\nwith some care.  Fortunately, there\u0027s not a lot of call sites,\nand with few exceptions all of those fall under one of the\ncases above.\n\nExceptions are all in fs/namei.c - in lookup_fast(), lookup_dcache()\nand mountpoint_last().  Another one is lookup_slow() - there\ndcache lookup is done with parent held shared, but the result\nis used after we\u0027d drop the lock.  The same happens in do_last() -\nthe lookup (in lookup_one()) is done with parent locked, but\nresult is used after unlocking.\n\nlookup_fast(), do_last() and mountpoint_last() flat-out reject\nnegatives.\n\nMost of lookup_dcache() calls are made with parent locked at least\nshared; the only exception is lookup_one_len_unlocked().  It might\nreturn pinned negative, needs serious care from callers.  Fortunately,\nalmost nobody calls it directly anymore; all but two callers have\nconverted to lookup_positive_unlocked(), which rejects negatives.\n\nlookup_slow() is called by the same lookup_one_len_unlocked() (see\nabove), mountpoint_last() and walk_component().  In those two negatives\nare rejected.\n\nIn other words, there is a small set of places where we need to\ncheck carefully if a pinned potentially negative dentry is, in\nfact, positive.  After that check we want to be sure that both\n-\u003ed_inode and type bits in -\u003ed_flags are stable and observed.\nThe set consists of follow_managed() (where the rejection happens\nfor lookup_fast(), walk_component() and do_last()), last_mountpoint()\nand lookup_positive_unlocked().\n\nSolution:\n\t1) transition from negative to positive (in __d_set_inode_and_type())\nstores -\u003ed_inode, then uses smp_store_release() to set -\u003ed_flags type bits.\n\t2) aforementioned 3 places in fs/namei.c fetch -\u003ed_flags with\nsmp_load_acquire() and bugger off if it type bits say \"negative\".\nThat way anyone downstream of those checks has dentry know positive pinned,\nwith -\u003ed_inode and type bits of -\u003ed_flags stable and observed.\n\nI considered splitting off d_lookup_positive(), so that the checks could\nbe done right there, under -\u003ed_lock.  However, that leads to massive\nduplication of rather subtle code in fs/namei.c and fs/dcache.c.  It\u0027s\nworse than it might seem, thanks to autofs -\u003ed_manage() getting involved ;-/\nNo matter what, autofs_d_manage()/autofs_d_automount() must live with\nthe possibility of pinned negative dentry passed their way, becoming\npositive under them - that\u0027s the intended behaviour when lookup comes\nin the middle of automount in progress, so we can\u0027t keep them out of\nthe area that has to deal with those, more\u0027s the pity...\n\nReported-by: Ritesh Harjani \u003criteshh@linux.ibm.com\u003e\nSigned-off-by: Al Viro \u003cviro@zeniv.linux.org.uk\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "b2a7f1765f0b12192c68a4638e1edd479aa00efa",
      "old_mode": 33188,
      "old_path": "fs/dcache.c",
      "new_id": "a6d6b5f95f62718f53f782864ac906c18a3cd2f6",
      "new_mode": 33188,
      "new_path": "fs/dcache.c"
    },
    {
      "type": "modify",
      "old_id": "6f72fb7ef5ad2f1c7c8b792bfa9bb2b5d2cfd832",
      "old_mode": 33188,
      "old_path": "fs/namei.c",
      "new_id": "117950657e63f525904689e93bc9c4f70e5b3273",
      "new_mode": 33188,
      "new_path": "fs/namei.c"
    }
  ]
}
