In the Linux kernel, the following vulnerability has been resolved:
smb: client: pin DFS superblock in iterator callback
tcon_super_cb() stores a raw superblock pointer, but __cifs_get_super()
takes its active reference only after iterate_supers_type() has dropped
s_umount and its passive reference. Concurrent DFS automount expiry can
therefore free the superblock before cifs_sb_active() uses it.
A deterministic KASAN test reproduces the race as:
BUG: KASAN: slab-use-after-free in cifs_sb_active+0x77/0x80
The same test passes with this change applied.
Take the active reference in the callback while iterate_supers_type()
still holds s_umount shared. cifs_put_tcp_super() remains the matching
release.
CVSS Vector: CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H
CVSS Score: 7.5
AV:N - The racing side is started by the remote SMB server: dropping the session or replying STATUS_NETWORK_NAME_DELETED makes the client run smb2_reconnect() -> cifs_tree_connect() -> cifs_get_dfs_tcon_super() -> __cifs_get_super(). There, tcon_super_cb() saves a raw superblock pointer that is used after s_umount is released.
AC:H - The server can force reconnects repeatedly, but the superblock is only freed if a DFS-link automount expires via cifs_expire_automounts() (a 500s periodic timer, idle submount only) inside the small gap between iterate_supers_type() returning and cifs_sb_active(). The attacker does not control that timing.
PR:N - The attacker is the SMB/DFS server or a network peer that can reset the client's session. Forcing the client's tree reconnect needs no account or privilege on the client.
UI:R - A victim must have mounted a DFS share with an automounted DFS link from the attacker-reachable server (cifs mounts need real CAP_SYS_ADMIN, not a user namespace), and the link must be idle long enough to expire.
S:U - The use-after-free corrupts memory in the same kernel that runs the CIFS client, so no separate security authority is crossed.
C:H - After the freed super_block and cifs_sb_info are reused, the reconnect path keeps reading them (cifs_sb_active() on freed memory, then CIFS_SB(sb) fields in tree_connect_dfs_target()), so reclaimed slab contents can be read.
I:H - cifs_sb_active() increments counters in the freed cifs_sb/sb, and cifs_update_super_prepath() frees and replaces cifs_sb->prepath in the freed cifs_sb_info. Both are writes into freed memory that can be turned into heap corruption.
A:H - The fix commit reports a KASAN slab-use-after-free in cifs_sb_active(); without KASAN the corrupted superblock refcounts and the later cifs_put_tcp_super()/deactivate_super() can crash the kernel.
| Attack Vector |
Network |
Scope |
Unchanged |
| Attack Complexity |
High |
Confidentiality Impact |
High |
| Privileges Required |
None |
Integrity Impact |
High |
| User Interaction |
Required |
Availability Impact |
High |
AV:N - The racing side is started by the remote SMB server: dropping the session or replying STATUS_NETWORK_NAME_DELETED makes the client run smb2_reconnect() -> cifs_tree_connect() -> cifs_get_dfs_tcon_super() -> __cifs_get_super(). There, tcon_super_cb() saves a raw superblock pointer that is used after s_umount is released.
AC:H - The server can force reconnects repeatedly, but the superblock is only freed if a DFS-link automount expires via cifs_expire_automounts() (a 500s periodic timer, idle submount only) inside the small gap between iterate_supers_type() returning and cifs_sb_active(). The attacker does not control that timing.
PR:N - The attacker is the SMB/DFS server or a network peer that can reset the client's session. Forcing the client's tree reconnect needs no account or privilege on the client.
UI:R - A victim must have mounted a DFS share with an automounted DFS link from the attacker-reachable server (cifs mounts need real CAP_SYS_ADMIN, not a user namespace), and the link must be idle long enough to expire.
S:U - The use-after-free corrupts memory in the same kernel that runs the CIFS client, so no separate security authority is crossed.
C:H - After the freed super_block and cifs_sb_info are reused, the reconnect path keeps reading them (cifs_sb_active() on freed memory, then CIFS_SB(sb) fields in tree_connect_dfs_target()), so reclaimed slab contents can be read.
I:H - cifs_sb_active() increments counters in the freed cifs_sb/sb, and cifs_update_super_prepath() frees and replaces cifs_sb->prepath in the freed cifs_sb_info. Both are writes into freed memory that can be turned into heap corruption.
A:H - The fix commit reports a KASAN slab-use-after-free in cifs_sb_active(); without KASAN the corrupted superblock refcounts and the later cifs_put_tcp_super()/deactivate_super() can crash the kernel.
CVSS 3.1