)]}'
{
  "commit": "d8ca920cdabd807e53b3530531b060b332a2f44b",
  "tree": "dd62fa273fa9584c791a9c1fd3049851f26e151a",
  "parents": [
    "8e006798c417bc16c1f301f7192a95fc6f090699"
  ],
  "author": {
    "name": "Zhihao Cheng",
    "email": "chengzhihao1@huawei.com",
    "time": "Fri Aug 09 11:16:28 2024 +0800"
  },
  "committer": {
    "name": "Oleksandr Tymoshenko",
    "email": "ovt@google.com",
    "time": "Fri Oct 11 19:31:48 2024 +0000"
  },
  "message": "vfs: Don\u0027t evict inode under the inode lru traversing context\n\ncommit 2a0629834cd82f05d424bbc193374f9a43d1f87d upstream.\n\nThe inode reclaiming process(See function prune_icache_sb) collects all\nreclaimable inodes and mark them with I_FREEING flag at first, at that\ntime, other processes will be stuck if they try getting these inodes\n(See function find_inode_fast), then the reclaiming process destroy the\ninodes by function dispose_list(). Some filesystems(eg. ext4 with\nea_inode feature, ubifs with xattr) may do inode lookup in the inode\nevicting callback function, if the inode lookup is operated under the\ninode lru traversing context, deadlock problems may happen.\n\nCase 1: In function ext4_evict_inode(), the ea inode lookup could happen\n        if ea_inode feature is enabled, the lookup process will be stuck\n\tunder the evicting context like this:\n\n 1. File A has inode i_reg and an ea inode i_ea\n 2. getfattr(A, xattr_buf) // i_ea is added into lru // lru-\u003ei_ea\n 3. Then, following three processes running like this:\n\n    PA                              PB\n echo 2 \u003e /proc/sys/vm/drop_caches\n  shrink_slab\n   prune_dcache_sb\n   // i_reg is added into lru, lru-\u003ei_ea-\u003ei_reg\n   prune_icache_sb\n    list_lru_walk_one\n     inode_lru_isolate\n      i_ea-\u003ei_state |\u003d I_FREEING // set inode state\n     inode_lru_isolate\n      __iget(i_reg)\n      spin_unlock(\u0026i_reg-\u003ei_lock)\n      spin_unlock(lru_lock)\n                                     rm file A\n                                      i_reg-\u003enlink \u003d 0\n      iput(i_reg) // i_reg-\u003enlink is 0, do evict\n       ext4_evict_inode\n        ext4_xattr_delete_inode\n         ext4_xattr_inode_dec_ref_all\n          ext4_xattr_inode_iget\n           ext4_iget(i_ea-\u003ei_ino)\n            iget_locked\n             find_inode_fast\n              __wait_on_freeing_inode(i_ea) ----→ AA deadlock\n    dispose_list // cannot be executed by prune_icache_sb\n     wake_up_bit(\u0026i_ea-\u003ei_state)\n\nCase 2: In deleted inode writing function ubifs_jnl_write_inode(), file\n        deleting process holds BASEHD\u0027s wbuf-\u003eio_mutex while getting the\n\txattr inode, which could race with inode reclaiming process(The\n        reclaiming process could try locking BASEHD\u0027s wbuf-\u003eio_mutex in\n\tinode evicting function), then an ABBA deadlock problem would\n\thappen as following:\n\n 1. File A has inode ia and a xattr(with inode ixa), regular file B has\n    inode ib and a xattr.\n 2. getfattr(A, xattr_buf) // ixa is added into lru // lru-\u003eixa\n 3. Then, following three processes running like this:\n\n        PA                PB                        PC\n                echo 2 \u003e /proc/sys/vm/drop_caches\n                 shrink_slab\n                  prune_dcache_sb\n                  // ib and ia are added into lru, lru-\u003eixa-\u003eib-\u003eia\n                  prune_icache_sb\n                   list_lru_walk_one\n                    inode_lru_isolate\n                     ixa-\u003ei_state |\u003d I_FREEING // set inode state\n                    inode_lru_isolate\n                     __iget(ib)\n                     spin_unlock(\u0026ib-\u003ei_lock)\n                     spin_unlock(lru_lock)\n                                                   rm file B\n                                                    ib-\u003enlink \u003d 0\n rm file A\n  iput(ia)\n   ubifs_evict_inode(ia)\n    ubifs_jnl_delete_inode(ia)\n     ubifs_jnl_write_inode(ia)\n      make_reservation(BASEHD) // Lock wbuf-\u003eio_mutex\n      ubifs_iget(ixa-\u003ei_ino)\n       iget_locked\n        find_inode_fast\n         __wait_on_freeing_inode(ixa)\n          |          iput(ib) // ib-\u003enlink is 0, do evict\n          |           ubifs_evict_inode\n          |            ubifs_jnl_delete_inode(ib)\n          ↓             ubifs_jnl_write_inode\n     ABBA deadlock ←-----make_reservation(BASEHD)\n                   dispose_list // cannot be executed by prune_icache_sb\n                    wake_up_bit(\u0026ixa-\u003ei_state)\n\nFix the possible deadlock by using new inode state flag I_LRU_ISOLATING\nto pin the inode in memory while inode_lru_isolate() reclaims its pages\ninstead of using ordinary inode reference. This way inode deletion\ncannot be triggered from inode_lru_isolate() thus avoiding the deadlock.\nevict() is made to wait for I_LRU_ISOLATING to be cleared before\nproceeding with inode cleanup.\n\nBUG\u003db/372637382\nTEST\u003dpresubmit\nRELEASE_NOTE\u003dFixed CVE-2024-45003 in the Linux kernel.\n\ncos-patch: security-moderate\nLink: https://lore.kernel.org/all/37c29c42-7685-d1f0-067d-63582ffac405@huaweicloud.com/\nLink: https://bugzilla.kernel.org/show_bug.cgi?id\u003d219022\nFixes: e50e5129f384 (\"ext4: xattr-in-inode support\")\nFixes: 7959cf3a7506 (\"ubifs: journal: Handle xattrs like files\")\nCc: stable@vger.kernel.org\nChange-Id: I438687d144da76e50146748135c35ee083455bd4\nSigned-off-by: Zhihao Cheng \u003cchengzhihao1@huawei.com\u003e\nLink: https://lore.kernel.org/r/20240809031628.1069873-1-chengzhihao@huaweicloud.com\nReviewed-by: Jan Kara \u003cjack@suse.cz\u003e\nSuggested-by: Jan Kara \u003cjack@suse.cz\u003e\nSuggested-by: Mateusz Guzik \u003cmjguzik@gmail.com\u003e\nSigned-off-by: Christian Brauner \u003cbrauner@kernel.org\u003e\nSigned-off-by: Greg Kroah-Hartman \u003cgregkh@linuxfoundation.org\u003e\nSigned-off-by: Kernel CVE Triage Automation \u003ccloud-image-kernel-cve-triage-automation@prod.google.com\u003e\nReviewed-on: https://cos-review.googlesource.com/c/third_party/kernel/+/83379\nTested-by: Cusky Presubmit Bot \u003cpresubmit@cos-infra-prod.iam.gserviceaccount.com\u003e\nReviewed-by: Arnav Kansal \u003crnv@google.com\u003e\nReviewed-by: Kevin Berry \u003ckpberry@google.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "ec41a11e2f8feff68368ee4186b94c73daba04c8",
      "old_mode": 33188,
      "old_path": "fs/inode.c",
      "new_id": "f957c130c7a6a508e18d99404dc102131dcc2a1e",
      "new_mode": 33188,
      "new_path": "fs/inode.c"
    },
    {
      "type": "modify",
      "old_id": "61e86502fe65e316db7e93ce6bad7e1e2c061b8b",
      "old_mode": 33188,
      "old_path": "include/linux/fs.h",
      "new_id": "27da89d0ed5acc6e2c3ea8294dde88436fe5b09e",
      "new_mode": 33188,
      "new_path": "include/linux/fs.h"
    }
  ]
}
