NFSD: Prevent lock owner use-after-free during client teardown
In the Linux kernel, the following vulnerability has been resolved:
NFSD: Prevent lock owner use-after-free during client teardown
__destroy_client() releases a client's open owners, but a lock owner
whose only reference is a blocked lock (nbl) stays on
cl_ownerstr_hashtbl. client_has_state() does not count a bare owner,
so DESTROY_CLIENTID can reach __destroy_client() with such owners
present.
__destroy_client() then walks the table, calling remove_blocked_locks()
on each owner without a reference. Freeing a blocked lock drops the
owner reference held via flc_owner. The per-net laundromat reaps
blocked locks from nn->blocked_locks_lru
NFSD: Prevent post-shutdown use-after-free in unlock_filesystem
In the Linux kernel, the following vulnerability has been resolved:
NFSD: Prevent post-shutdown use-after-free in unlock_filesystem
Writing a filesystem path to /proc/fs/nfsd/unlock_filesystem runs
nfsd4_cancel_copy_by_sb() before nfsd_mutex is held and before the
handler confirms that nn->nfsd_serv is set. Once nfsd has shut down,
nfs4_state_destroy_net() has freed nn->conf_id_hashtbl but left the
pointer intact, so the cancel helper iterates freed slab memory as an
array of struct list_head and then dereferences a bogus nfs4_client
when it takes clp->async_lock. A local administrator holding
CAP_SYS_ADMIN can reach this use-after-free by
NFSD: Prevent client use-after-free during admin state revocation
In the Linux kernel, the following vulnerability has been resolved:
NFSD: Prevent client use-after-free during admin state revocation
A stateid holds only a bare pointer to its nfs4_client; a stateid
reference does not pin it. The client survives only because
__destroy_client() drains its stateids before free_client() runs.
nfsd4_revoke_states() drops nn->client_lock across revoke_one_stid(),
which dereferences the client to revoke a stateid and read
clp->cl_minorversion. A teardown racing the dropped lock can free
the client first.
Pinning cl_rpc_users under client_lock blocks the DESTROY_CLIENTID and
EXCHANGE_ID teardown, which refuse
NFSD: Prevent client use-after-free during delegation revoke
In the Linux kernel, the following vulnerability has been resolved:
NFSD: Prevent client use-after-free during delegation revoke
A delegation stateid holds only a bare pointer to its owning
nfs4_client and does not keep it alive. The client survives its
stateids only because __destroy_client() drains cl_delegations and
cl_revoked before free_client() runs.
nfs4_laundromat() breaks that invariant: it unhashes an
expired delegation from cl_delegations, drops deleg_lock, then
revoke_delegation() relinks it onto cl_revoked under cl_lock. In that
window the delegation is on neither list, so client_has_state() can
report no remaining state.
E
NFSD: Prevent client use-after-free during NFSv4.0 revoked-state cleanup
In the Linux kernel, the following vulnerability has been resolved:
NFSD: Prevent client use-after-free during NFSv4.0 revoked-state cleanup
nfs40_clean_admin_revoked() takes a stateid reference under
clp->cl_lock, drops nn->client_lock, and calls
nfsd4_drop_revoked_stid(), which dereferences the stateid's client
through s->sc_client->cl_lock. The stateid reference does not pin the
client, so a teardown racing the dropped lock can free the client
while nfsd4_drop_revoked_stid() is still using it.
This cleanup runs from the laundromat, so a periodic sweep can race
force_expire_client() driven by a write to the clients/<id>/ctl file.
Skip
libceph: validate OSD extent maps before cursor advance
In the Linux kernel, the following vulnerability has been resolved:
libceph: validate OSD extent maps before cursor advance
net/ceph/osd_client.c:osd_sparse_read() validates that the sparse-read
data length matches the summed extent lengths, but it does not validate
that each OSD-supplied extent is monotonic and lies inside the original
request range. A malformed authenticated OSD reply can advertise a
far-forward nonzero extent offset with a matching data length and make
the client advance the message-data cursor beyond the request buffer.
This reaches the BUG_ON(!*length) assertion in ceph_msg_data_next() from
the client receive path.
Im
In the Linux kernel, the following vulnerability has been resolved:
libceph: reject buckets with mismatched CRUSH ids
crush_decode() stores bucket data by array slot, and the mapper later
derives the per-bucket workspace index from the decoded bucket id. A
malformed map can therefore make one bucket reuse another bucket's
workspace by encoding an id different from -1 - slot.
For uniform buckets, the second replica selection expands the source
bucket's permutation into that aliased workspace buffer. If the source
bucket is larger than the aliased bucket, the write runs past the smaller
permutation array and can escape the kvmalloc'd CRUSH w
ceph: fix UAF in __kick_flushing_caps() on cf entry freed during unlock
In the Linux kernel, the following vulnerability has been resolved:
ceph: fix UAF in __kick_flushing_caps() on cf entry freed during unlock
list_for_each_entry() iterates ci->i_cap_flush_list but drops
i_ceph_lock to send cap messages. During the unlock window,
handle_cap_flush_ack() can acquire i_ceph_lock, detach cf entries
with tid <= flush_tid from the list, release i_ceph_lock, and free
them via ceph_free_cap_flush() outside any lock. When the original
thread reacquires i_ceph_lock and the for-loop macro advances via
cf = list_next_entry(cf, i_list), it dereferences cf->i_list.next
on freed memory.
The race timeline:
__kick_flush
ceph: fix UAF in check_new_map() on session freed during unlock
In the Linux kernel, the following vulnerability has been resolved:
ceph: fix UAF in check_new_map() on session freed during unlock
check_new_map() iterates mdsc->sessions[] and for each active session
drops mdsc->mutex to perform per-session operations. The forced-close
path (rank removed from map) correctly takes a reference on s via
ceph_get_mds_session() before releasing mdsc->mutex, but three other
paths do not:
Path A (address changed): mutex_unlock → mutex_lock(&s->s_mutex)
Path B (reconnect): mutex_unlock → send_mds_reconnect(mdsc, s)
Path C (active transition): mutex_unlock → mutex_lock(&s->s_mutex)
Without the ext
ceph: reject export_targets ranks >= CEPH_MAX_MDS in mdsmap decode
In the Linux kernel, the following vulnerability has been resolved:
ceph: reject export_targets ranks >= CEPH_MAX_MDS in mdsmap decode
MDSMap export_targets entries are monitor controlled. check_new_map()
uses each entry as a bit number in a fixed stack bitmap, so a rank
outside the protocol namespace can make set_bit() write past the end of
the array.
Reject ranks outside CEPH_MAX_MDS while decoding the map. Do not
validate against possible_max_rank here because maps may legitimately
reference ranks beyond a temporarily reduced max_mds.
ceph: bound copied dentry name length in NFS export get_name
In the Linux kernel, the following vulnerability has been resolved:
ceph: bound copied dentry name length in NFS export get_name
ceph_get_name() copies the MDS-supplied name into the caller's
NAME_MAX-sized buffer with memcpy(name, rinfo->dname, rinfo->dname_len)
and then writes name[rinfo->dname_len] = 0, without checking dname_len
against NAME_MAX. A malicious or buggy MDS that returns a LOOKUPNAME reply
with dname_len > NAME_MAX overflows the buffer. __get_snap_name() copies
rde->name / rde->name_len the same unchecked way.
Impact: a malicious or compromised Ceph MDS overflows the NAME_MAX name
buffer in a client's NFS-export get_name p
ceph: bound MDSCapAuth path and fs_name decode in handle_session()
In the Linux kernel, the following vulnerability has been resolved:
ceph: bound MDSCapAuth path and fs_name decode in handle_session()
handle_session() decodes the MDSCapAuth records carried by a
CEPH_SESSION_OPEN message (msg_version >= 6). For each record the
match.path and match.fs_name byte strings are read by first decoding a
32-bit length and then copying that many bytes with the bare
ceph_decode_copy(). Unlike the surrounding fields, which all use the
_safe decode variants, these two copies are not preceded by a
ceph_decode_need() bounds check, and the enclosing MDSCapAuth and
MDSCapMatch struct_len fields are skipped rather than enf
ceph: bound num_export_targets array for mds info v2/v3
In the Linux kernel, the following vulnerability has been resolved:
ceph: bound num_export_targets array for mds info v2/v3
ceph_mdsmap_decode() in fs/ceph/mdsmap.c reads num_export_targets from
each per-mds info record and advances the decode cursor by
num_export_targets * sizeof(u32) without first checking that many bytes
remain. The only upper-bound check that catches a runaway cursor
(*p > info_end) is gated on info_v >= 4, because info_end is left NULL
for info_v 2 and 3. When the monitor sends an MDS map whose per-mds
info version is 2 or 3 with an oversized num_export_targets, the cursor
moves past the message front buffer and the la
ceph: bound xattr value length in __build_xattrs()
In the Linux kernel, the following vulnerability has been resolved:
ceph: bound xattr value length in __build_xattrs()
__build_xattrs() decodes the MDS-supplied xattr blob one attribute at a
time. For each attribute it reads a 32-bit name length, advances past the
name bytes, reads a 32-bit value length, records the value pointer, and
advances past the value bytes. The two length fields are read with
ceph_decode_32_safe(), but the value bytes themselves are advanced over
with a bare "p += len" and no ceph_decode_need() check that "len" bytes
remain in the blob.
For every attribute except the last, the next iteration's
ceph_decode_32_safe()
ceph: cap delegated inode count in ceph_parse_deleg_inos()
In the Linux kernel, the following vulnerability has been resolved:
ceph: cap delegated inode count in ceph_parse_deleg_inos()
ceph_parse_deleg_inos() decodes interval sets of delegated inode numbers
from an MDS create-with-delegation reply. For each set it reads a 64-bit
start and a 64-bit len with ceph_decode_64_safe(), which only validates
that the eight bytes are present in the message, not the value, and then
loops over len while inserting entries into s_delegated_inos.
len is fully attacker controlled. A malicious or compromised MDS can send
one huge interval, many intervals in one reply, duplicate intervals, or
repeated replies that
ceph: do not repeat ceph_trim_dentries() if no progress possible
In the Linux kernel, the following vulnerability has been resolved:
ceph: do not repeat ceph_trim_dentries() if no progress possible
ceph_cap_reclaim_work() re-queues itself for as long as
ceph_trim_dentries() returns -EAGAIN, which happens whenever a lease
walk exhausts its `nr_to_scan` budget. This creates a busy loop that
consumes CPU without making any progress when there is nothing to
reclaim: with no cap pressure (`count==0`) and every scanned lease
still valid, each pass runs the full scan budget down to zero and
returns `-EAGAIN`, only to be queued again immediately.
The dir-lease walk made this worse. When `expire_dir_lease` is
ceph: fix leaked inode reference on writeback abort at umount
In the Linux kernel, the following vulnerability has been resolved:
ceph: fix leaked inode reference on writeback abort at umount
ceph_dirty_folio() takes a wrbuffer claim on each newly dirtied folio: it
bumps i_wrbuffer_ref (taking an ihold() on the 0->1 transition) and
attaches the snap_context to folio->private. That claim is released only
by ceph_put_wrbuffer_cap_refs(), which for a submitted write runs from
writepages_finish().
In ceph_submit_write(), if ceph_inc_osd_stopping_blocker() fails -- which
happens during umount -- the request is aborted before submission: the
already-collected folios are only redirtied and unlocked, so
wri
btrfs: drop recovered reloc root refs on recovery failure
In the Linux kernel, the following vulnerability has been resolved:
btrfs: drop recovered reloc root refs on recovery failure
During relocation recovery, each fs root gets a reference to its relocation
root. If loading or adding a later root fails, or if the first transaction
commit fails, btrfs_recover_relocation() jumps to out_unset before
merge_reloc_roots() and clean_dirty_subvols().
put_reloc_control() drops the list-owned relocation root references, but it
does not clear fs_root->reloc_root or drop the references owned by those
pointers. Mount cleanup only drops them when BTRFS_FS_ERROR is set, so an
error such as -ENOMEM while proce
btrfs: fix extent map leak in NOCOW direct I/O write
In the Linux kernel, the following vulnerability has been resolved:
btrfs: fix extent map leak in NOCOW direct I/O write
btrfs_dio_iomap_begin() calls btrfs_get_extent(), which returns an
extent map reference that must be dropped on all exit paths.
For direct writes into a NOCOW range, btrfs_get_blocks_direct_write()
keeps using that extent map and asks btrfs_create_dio_extent() to
allocate the ordered extent. If that fails, for example because
btrfs_alloc_ordered_extent() fails, the function returns the error
without dropping the input extent map. The PREALLOC path avoided this by
dropping the input extent map before replacing it with the
audit: avoid dropping live tree ref on fsnotify rule autoremove
In the Linux kernel, the following vulnerability has been resolved:
audit: avoid dropping live tree ref on fsnotify rule autoremove
audit_del_rule() is used for both netlink deletion templates and internal
fsnotify autoremove. The former passes a parsed template which owns a
temporary tree reference; the latter passes the installed entry itself.
The unconditional audit_put_tree() at the end of audit_del_rule() assumes
the template case. For mixed AUDIT_DIR plus AUDIT_EXE rules, an fsnotify
autoremove event therefore drops the installed rule's live tree reference.
Repeating this across rules sharing the same tree can free the tree while
a