diff options
| author | Yu Zhang <yuz08559@gmail.com> | 2026-10-14 11:37:46 +1000 |
|---|---|---|
| committer | Martin K. Petersen (Oracle) <mkp@kernel.org> | 2026-10-28 21:41:31 -0400 |
| commit | 6a6e7d7230cd4e0a6c003bae5b85bf37a1e77b94 (patch) | |
| tree | 328d6818d3fbab4c9011c66811e3c4aee76903b0 /scripts/dummy-tools/python3 | |
| parent | 9ec6671b137de06f0345962fb8091466b7d56a96 (diff) | |
scsi: target: Fix demo-mode dynamic ACL dev-entry UAF vs LUN teardown
A demo-mode (generate_node_acls=1) login that allocates a dynamic NodeACL
populates that ACL's per-LUN dev entries in core_tpg_add_node_to_devs()
*before* the ACL is linked onto tpg->acl_node_list by
target_add_node_acl():
core_tpg_check_initiator_node_acl():
...
core_tpg_add_node_to_devs(acl, tpg, NULL); /* builds deves */
target_add_node_acl(acl); /* only now listed */
The LUN teardown sweep, core_clear_lun_from_tpg(), enumerates only
tpg->acl_node_list, so a dev entry whose ACL is still in the window above
is invisible to the sweep and is never disabled. It is left on the
se_lun->lun_deve_list after core_tpg_remove_lun() frees the se_lun; when
the same unpacked_lun is later re-added and the se_lun is reallocated at
the same address, the stale dev entry is rediscovered by
target_nacl_find_deve() and core_enable_device_list_for_node() corrupts
lun_deve_list:
BUG: KASAN: slab-use-after-free ...
core_enable_device_list_for_node+0x5ce/0x880
core_tpg_add_node_to_devs+0x169/0x190
core_dev_add_lun+0x146/0x190
target_fabric_port_link+0xe9/0x1b0
configfs_symlink+0x381/0xae0
__x64_sys_symlink+0x55/0x80
The demo-mode login path that drives the ACL/dev-entry creation is
reachable by an unauthenticated initiator; the colliding LUN add/remove is
a local configfs operation.
Commit 49cb77e297dc ("target: Avoid mappedlun symlink creation during lun
shutdown") introduced se_lun->lun_shutdown and guarded the *explicit* ACL
MappedLUN path (target_fabric_mappedlun_link()), but the demo-mode
automatic path, core_tpg_add_node_to_devs() ->
core_enable_device_list_for_node(), was never given the equivalent guard,
and the publish-after-populate ordering in
core_tpg_check_initiator_node_acl() was left unchanged.
Fix it in three cooperating parts:
1) Publish the dynamic NodeACL onto acl_node_list *before* creating its
dev entries, so the teardown sweep can observe them.
2) Refuse to attach a dev entry to an se_lun that is shutting down,
checked under nacl->lun_entry_mutex -- the same lock the sweep takes --
so once the sweep has passed an ACL any later enable for that LUN
observes lun_shutdown and skips it.
3) In core_enable_device_list_for_node(), insert the new dev entry onto
lun->lun_deve_list while still holding nacl->lun_entry_mutex, in both
the replace and the new-entry branch. Previously the entry was added
to nacl->lun_entry_hlist under the mutex but to lun->lun_deve_list only
after dropping it; with the ACL now published early, the sweep could
take the mutex in that gap, find the entry on the hlist,
core_disable_device_list_for_node() it (list_del() on the not-yet-
linked lun_link succeeds and the entry is freed), and then the enable
would list_add_tail() the freed entry back onto lun_deve_list. Linking
both lists under the mutex makes enable and the sweep mutually
exclusive, closing that window.
core_tpg_add_node_to_devs() already ignores the return value of
core_enable_device_list_for_node(), so a shutting-down LUN is simply
skipped.
Cc: stable@vger.kernel.org
Fixes: 49cb77e297dc ("target: Avoid mappedlun symlink creation during lun shutdown")
Signed-off-by: Yu Zhang <yuz08559@gmail.com>
Tested-by: Yu Zhang <yuz08559@gmail.com>
Link: https://patch.msgid.link/20261014013746.46705-1-yuz08559@gmail.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Diffstat (limited to 'scripts/dummy-tools/python3')
0 files changed, 0 insertions, 0 deletions
