mirror of
https://github.com/torvalds/linux.git
synced 2026-10-17 14:30:03 +02:00
master
108670 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c93b3c43df |
btrfs: detach failed sprout device from transaction update list
When creating the first metadata chunk for a sprout filesystem,
create_chunk() adds the new device to the transaction dev_update_list
through device->post_commit_list.
If the subsequent system chunk creation fails, btrfs_init_new_device()
aborts the transaction and releases the device while post_commit_list is
still linked. This triggers a warning in btrfs_free_device() and leaves
the transaction list referencing freed memory.
Detach the device while holding chunk_mutex before releasing it.
Fixes:
|
||
|
|
40fe154ba0 |
btrfs: clean up target device if block group marking fails
btrfs_dev_replace_start() adds the replacement target to the device list before marking block groups to copy. If marking fails, returning directly leaves the target linked and keeps the device accounting incremented. Jump to the existing cleanup path so the target device is removed and released on failure. The issue was found by a failure-path metadata residual analyzer and verified with targeted failure injection on v6.14. Assisted-by: Codex:gpt-5 Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Guanghui Yang <3497809730@qq.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> |
||
|
|
89a312991d |
SMB client fixes for v7.3-rc2
A batch of bug fixes for the SMB client:
- Fixes for fallocate range operations (insert, collapse, zero, punch
hole): the insert range implementation copied overlapping chunks in
the wrong direction, corrupting file data on every server except
Windows. Several related issues in the same area are also
addressed — stale page cache and FS-Cache readback, an integer
truncation on large files, missing RLIMIT_FSIZE validation and
missing sparse file marking.
- Data corruption fixes in the O_TRUNC open path: one where i_size
was zeroed before the server confirmed the truncate and another
where the lack of locking allowed concurrent buffered writes to be
silently discarded.
- Heap overflow fixes in legacy SMB1 paths: one in extended attribute
writes and one in POSIX ACL handling, both exploitable via
unprivileged setxattr(2).
- Fix for multiuser mount with krb5 failing because the username
option was not propagated to new per-user connections.
- Fix for split debug message in __release_mid() after a printk
conversion.
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQTcqRusfSdYROJQwGkpVtNKoQNdYwUCapcv6wAKCRApVtNKoQNd
Y0dgAQDvlnpdCsg1SZZN7T/wSy08fP7GEl2lUoCb8m6LQHlDlwEA/RG+FeY8sRkb
iJexqIGT85a48SHmpSavzBO3qkuqIQo=
=+Qbr
-----END PGP SIGNATURE-----
Merge tag 'cifs-fixes-7.3-rc2' of https://git.manguebit.org/linux
Pull smb client fixes from Paulo Alcantara:
- Fixes for fallocate range operations (insert, collapse, zero, punch
hole)
The insert range implementation copied overlapping chunks in the
wrong direction, corrupting file data on every server except Windows.
Several related issues in the same area are also addressed — stale
page cache and FS-Cache readback, an integer truncation on large
files, missing RLIMIT_FSIZE validation and missing sparse file
marking.
- Data corruption fixes in the O_TRUNC open path: one where i_size was
zeroed before the server confirmed the truncate and another where the
lack of locking allowed concurrent buffered writes to be silently
discarded
- Heap overflow fixes in legacy SMB1 paths: one in extended attribute
writes and one in POSIX ACL handling, both exploitable via
unprivileged setxattr(2)
- Fix for multiuser mount with krb5 failing because the username option
was not propagated to new per-user connections
- Fix for split debug message in __release_mid() after a printk
conversion
* tag 'cifs-fixes-7.3-rc2' of https://git.manguebit.org/linux:
smb: client: reject SetEA requests that do not fit the request buffer
smb: client: fix data corruption with concurrent writes and O_TRUNC
cifs: don't update i_size in cifs_do_truncate without a cached handle
smb: client: fix heap overflow in cifs_do_set_acl()
smb: client: fix multiuser mount with krb5
smb: client: transport: Fix debug printing in __release_mid()
smb/client: invalidate fscache for fallocate range operations
smb/client: fix stale page cache in insert/collapse range
smb/client: fix integer truncation in collapse range
smb/client: fix data corruption in emulated insert range
smb/client: mark file sparse before emulating insert range
smb/client: validate new EOF for zero range
smb/client: validate new EOF for insert range
cifs: add revalidation on FSCTL failure in smb2_duplicate_extents()
|
||
|
|
9a58da8005 |
- Prevent unintended data exposure by clearing pipe compound padding and
the response buffer.
- Initialize missing fields in FS_OBJECT_ID_INFORMATION,
FS_CONTROL_INFORMATION, and FS_POSIX_INFORMATION.
- Propagate DACL parsing and allocation failures so malformed security
descriptors are rejected.
- Rate-limit errors for unmapped SIDs to prevent kernel log flooding.
- Drain multichannel sessions during LOGOFF, wake deferred locks and
cancellable requests, and ensure cancellation callbacks run only once.
- Fix listener kthread reference handling and teardown ordering during
netdevice events.
- Validate normalized-name and IPC share configuration response lengths.
- Update the KSMBD MAINTAINERS entry and add Paulo Alcantara as
an SMBDIRECT co-maintainer.
-----BEGIN PGP SIGNATURE-----
iQJKBAABCgA0FiEE6NzKS6Uv/XAAGHgyZwv7A1FEIQgFAmqWnz0WHGxpbmtpbmpl
b25Aa2VybmVsLm9yZwAKCRBnC/sDUUQhCJK8EACCE2K2p9CH6kiy9VnMjEqTbIBF
ZRCmxrspoPAMuTbK6529dXHUVTsXlUdJ/FVzGwNLtvXwEIVjNaQDqBEFWCdPElE+
8grKsC1S3gH3t8Z1wT6eNh5cpDoA+rWJDbNK4DsmHdoVagyjd9dd7fkMi7nq0WJS
NO7BTHaTuTaZDul8UXc1gqkVLviZZWkrtkGVVnsJV1z5cFls6P81cVmtzP0836cU
kVDYSI0EZnX+1P5CtOxL3r5LDBex6lRHU+rj1ypJRJDM2nR+bYIeJk+XMjylKCHT
liPj7dwI/ptVzp+n3dbcTyhLZayDhZ0/GeJanX2/midtiNSKhao9h94BymPU91jV
JugPlkAO8Vqwo7xojWRqudz4Kg/vgr66NexQ/3W2tuRXXFN4kEWmQG0N5+kH0K3d
sJ5xA9uLj24+d29fjylkdSGpuRLR8XcR01he2CaqLRopXZrCxFChwzZwbads1rI/
kXtYrORB0u99ScwTRQeW90dzeZ+1R3aHOyf8H86zyJ07l2NxG8t5L/49vuaiaiEZ
5r4hhPVumlmDQdPoOcugOmkJL68+W4TzS7UfcOSgq43W31BE1dYsaX7u4MHNk/Nq
UiWJJPArJ3ry8e4GLqQXx4ylZJnykGS9s676gFCO1GAI+eXoQ4R0k7RCKy/TW0ap
t3oa0Yj+Y4QAZCD3Rw==
=UL/J
-----END PGP SIGNATURE-----
Merge tag 'ksmbd-for-7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/smb
Pull smb server fixes from Namjae Jeon:
- Prevent unintended data exposure by clearing pipe compound padding
and the response buffer
- Initialize missing fields in FS_OBJECT_ID_INFORMATION,
FS_CONTROL_INFORMATION, and FS_POSIX_INFORMATION
- Propagate DACL parsing and allocation failures so malformed security
descriptors are rejected
- Rate-limit errors for unmapped SIDs to prevent kernel log flooding
- Drain multichannel sessions during LOGOFF, wake deferred locks and
cancellable requests, and ensure cancellation callbacks run only once
- Fix listener kthread reference handling and teardown ordering during
netdevice events
- Validate normalized-name and IPC share configuration response lengths
- Update the KSMBD MAINTAINERS entry and add Paulo Alcantara as an
SMBDIRECT co-maintainer
* tag 'ksmbd-for-7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/smb:
ksmbd: validate normalized name response length
ksmbd: fix listener task lifetime on netdev events
ksmbd: prevent out-of-bounds reads in share config responses
ksmbd: rate limit unmapped SID errors
ksmbd: propagate DACL parsing errors
ksmbd: zero pipe read compound padding
ksmbd: safely drain sessions during logoff
MAINTAINERS: Update the KSMBD entry
MAINTAINERS: Add Paulo Alcantara as an SMBDIRECT co-maintainer
ksmbd: fill in FileSysIdentifier in FS_POSIX_INFORMATION
ksmbd: initialize FileSystemControlFlags in FS_CONTROL_INFORMATION
ksmbd: zero the FS_OBJECT_ID_INFORMATION buffer before filling it in
|
||
|
|
7b15d6cf25 |
kernfs: preserve security xattrs without allocating iattrs
Commit |
||
|
|
a7f25dc23f |
xfs: fixes for 7.3-rc2
Signed-off-by: Carlos Maiolino <cem@kernel.org> -----BEGIN PGP SIGNATURE----- iJUEABMJAB0WIQSmtYVZ/MfVMGUq1GNcsMJ8RxYuYwUCapUNuQAKCRBcsMJ8RxYu Y/QVAX9SDXNSP3dw04wAuYgwSH5Ftm+WAnwusAsSvJkQdTvU0nEpAHyjb6WokS5a EbOGy5UBfRyqJFOmOw6wF5Ax0Aoxrt+lN8CuoDoh6aEhtYlh0jvd50ustYX8QSas W2R9B6IFIw== =JWP4 -----END PGP SIGNATURE----- Merge tag 'xfs-fixes-7.3-rc2' of gitolite.kernel.org:/pub/scm/fs/xfs/xfs-linux Pull xfs fixes from Carlos Maiolino: "This contains a few fixes for the zoned storage support, a possible deadlock vector fix, some code refactoring patches and a quota evasion fix on XFS while exporting it via NFS. Please note that for the quota evasion fix, a couple patches for the capability subsystem are included in the pull request. Those have been ack'ed by the respective maintainer which also agreed to have them going through the xfs tree. This also includes a patch for the quota subsystem to stop issuing audit messages during quota enforcing. Quota maintainer also ack'ed and agreed with this going through xfs tree" * tag 'xfs-fixes-7.3-rc2' of gitolite.kernel.org:/pub/scm/fs/xfs/xfs-linux: capability: unexport has_capability_noaudit xfs: replace ns_capable_noaudit quota: Don't issue audit messages on quota enforcing capability: Add new capable_noaudit xfs: fix capability check in xfs xfs: restore bi_bdev in xfs_zone_gc_write_chunk xfs: split ioend handling into a separate source file xfs: factor out a xfs_iomap_set_anon_write helper xfs: fix zoned write iomap flags assignments xfs: fix racy open zone caching xfs: handle NULL open_zone for merged ioends in xfs_ioend_put_open_zones xfs: use inode_init_always_gfp with __GFP_NOFAIL in xfs_inode_alloc xfs: remove kmem_to_page() xfs: don't flush and invalidate internal RT device twice in xfs_shutdown_devices xfs: split an assert in xfs_trans_log_buf xfs: don't hold buffer locks across sync transaction commit in xfs_sync_sb_buf |
||
|
|
4aa2c106ae |
smb: client: reject SetEA requests that do not fit the request buffer
CIFSSMBSetEA() copies the caller's extended attribute value into the
SMB request buffer without checking that it fits. The requirement is
stated in the source but was never implemented:
/*BB add length check to see if it would fit in
negotiated SMB buffer size BB */
/* if (ea_value_len > buffer_size - 512 (enough for header)) */
if (ea_value_len)
memcpy(parm_data->list.name + name_len + 1,
ea_value, ea_value_len);
The only bound applied on the way in is in cifs_xattr_set():
#define MAX_EA_VALUE_SIZE CIFSMaxBufSize
...
if (size > MAX_EA_VALUE_SIZE)
CIFSMaxBufSize is the full payload capacity of the buffer, so a value
of exactly that size leaves no room for the SMB header, the TRANS2
parameter block, the fealist header and the EA name that are written
ahead of it in the same object.
SendReceive() already enforces the correct limit on this very length:
if (in_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
but it is called after the copy has taken place. An unprivileged
setxattr(2) on an SMB1 mount with a 250-byte name and a 16384-byte
value writes 16384 bytes starting 345 bytes into a 16588-byte
cifs_request object, ending 141 bytes past it:
BUG: KASAN: slab-out-of-bounds in CIFSSMBSetEA+0xabc/0xde0
Write of size 16384 at addr ffff888003aa0159 by task init/68
__asan_memcpy+0x3c/0x60
CIFSSMBSetEA+0xabc/0xde0
cifs_xattr_set+0xd3a/0xff0
__vfs_setxattr+0x13e/0x1a0
The buggy address is located 345 bytes inside of
allocated 16588-byte region
Apply SendReceive()'s limit to the assembled request before the copy
rather than after it, and widen the byte counters so the sum cannot
wrap before it is tested.
byte_count is also tested against U16_MAX, because it is stored in the
16-bit pSMB->ByteCount. That becomes reachable when CIFSMaxBufSize is
raised at module load, where it may be set as high as 1024*127: with a
5-byte EA name and a 65521-byte value, count is exactly U16_MAX while
byte_count is 65556, and cpu_to_le16() would truncate it to 20 and
transmit a frame whose ByteCount does not match its length. Testing
byte_count covers count as well, since byte_count is the larger of the
two and count's only 16-bit consumer is written after this point.
check_add_overflow() is evaluated first so that total_len is assigned
before it is reported.
Fixes:
|
||
|
|
a8603b52b3 |
smb: client: fix data corruption with concurrent writes and O_TRUNC
cifs_do_truncate() flushes dirty pages with filemap_write_and_wait()
and truncates the file on the server, but in the old code both
operations ran without holding i_rwsem or invalidate_lock. A
concurrent buffered write via netfs_perform_write() -- which only
needs i_rwsem shared -- could dirty new pages after the flush but
before the local truncation, and those pages would be silently
discarded by cifs_setsize() -> truncate_pagecache().
Fix by acquiring inode_lock (exclusive i_rwsem) and
filemap_invalidate_lock at the top of cifs_do_truncate(), so the
entire flush-truncate-resize sequence is atomic with respect to:
- buffered writes (blocked by exclusive i_rwsem, since
netfs_start_io_write takes i_rwsem shared),
- read page faults (blocked by exclusive invalidate_lock, since
filemap_fault takes it shared),
- writeback collection (blocked by netfs_wb_begin/netfs_wb_end
around the server truncate and local resize, since
netfs_writepages also acquires the wb lock).
Fixes:
|
||
|
|
0fecc393f2 |
ntfs: take invalidate_lock in ntfs_filemap_page_mkwrite()
ntfs_filemap_page_mkwrite() calls iomap_page_mkwrite() without holding
mapping->invalidate_lock, so a concurrent truncate or fallocate can be
in the middle of invalidating pagecache and rewriting the runlist while
the write fault maps blocks and dirties the folio. This races with
ntfs_attr_fallocate(), which merges clusters into the in-memory
runlist, drops the runlist lock, and only afterwards zeroes the newly
allocated clusters on disk; and with the punch-hole/insert/collapse
paths that free clusters after truncating the cache.
Per Documentation/filesystems/locking.rst, ->page_mkwrite() must ensure
there are no truncate/invalidate races, "usually mapping->invalidate_lock
is suitable for proper serialization". xfs takes its mmaplock (= the
invalidate_lock rwsem) shared in exactly this path.
Take invalidate_lock shared around iomap_page_mkwrite(). The read-only
fault path is already covered because filemap_fault() itself grabs
invalidate_lock shared on instantiation/read paths; only page_mkwrite
was bypassing it in this driver.
Fixes:
|
||
|
|
9cc5761b8f |
ntfs: take invalidate_lock in ntfs_setattr_size()
ntfs_setattr_size() updates i_size and resizes the on-disk attribute
without holding mapping->invalidate_lock. Page faults take the lock
shared, so a fault racing the resize can resolve a VCN against the
transient runlist state of ntfs_non_resident_attr_expand() and fail
with a spurious SIGBUS, and can interleave with the size-change
epilogue (truncate_pagecache(), i_size_write(),
pagecache_isize_extended()).
Take invalidate_lock exclusively around the whole resize after
inode_dio_wait(), matching the fallocate path and other filesystems
such as xfs, which wraps truncate in its mmaplock (= invalidate_lock).
Fixes:
|
||
|
|
4dc8f4ee2d |
ntfs: handle signal interruption in fallocate
The ntfs_attr_fallocate() function checks for pending signals during
allocation loops and exits early via 'out' label. However, when a signal
interrupts the operation with err == 0, the function returns 0 (success)
instead of -EINTR.
The signal_pending() checks at the allocation loops jump to 'out' without
setting err = -EINTR, so the function returns success even when interrupted
by a signal.
Set err = -EINTR when jumping to the signal exit path, and only override
when no other error is pending. This ensures:
- Allocation interrupted by signal returns -EINTR
- Allocation that completed successfully before signal arrived returns 0
- Other errors are preserved and not overwritten by -EINTR
Fixes:
|
||
|
|
ba9572bc43 |
ksmbd: validate normalized name response length
FILE_NORMALIZED_NAME_INFORMATION converts the open file path to UTF-16.
smb2_allocate_rsp_buf() leaves these responses in the 448-byte small
buffer, and get_file_normalized_name_info() converts the path without
checking the remaining space.
An authenticated client can query a long path and make
smbConvertToUTF16() write beyond work->response_buf.
Use the large response buffer for normalized-name queries. Before
conversion, verify that the response has room for the worst-case UTF-16
output and its terminator.
Fixes:
|
||
|
|
a506290f59 |
ksmbd: fix listener task lifetime on netdev events
The listener thread exits when its listening socket is shutdown. The
netdevice notifier shuts down the socket before calling kthread_stop(), so
the task_struct can be freed before kthread_stop() gets its reference.
Create the listener in a stopped state and hold an extra task_struct
reference until kthread_stop_put() completes. Also stop and release
listeners before freeing their interface records during TCP teardown.
Fixes:
|
||
|
|
f25e93768f |
ksmbd: prevent out-of-bounds reads in share config responses
Validate IPC share configuration payload sizes before consuming
variable-length fields. Bound veto list parsing and account for
the separator byte when deriving the path length.
Fixes:
|
||
|
|
feca5e70fc |
ksmbd: rate limit unmapped SID errors
A client can include many structurally valid but unmapped SIDs in a DACL.
Logging every mapping failure lets one request generate hundreds of kernel
error messages.
Rate limit the message to prevent an authenticated client from flooding
the kernel log.
Fixes:
|
||
|
|
c61dc7b1b4 |
ksmbd: propagate DACL parsing errors
parse_dacl() silently accepts truncated ACEs and allocation failures,
allowing set_info_sec() to continue with an incomplete ACL conversion.
Return parsing and allocation errors to parse_sec_desc() so malformed
security descriptors are rejected before inode attributes or ACL xattrs
are updated.
Fixes:
|
||
|
|
73f860489e |
ksmbd: zero pipe read compound padding
Compound response handling extends the last response iov to an eight-byte
boundary.
smb2_read_pipe() allocates only the payload size, so the alignment padding
can expose up to seven bytes of uninitialized kernel heap memory.
Allocate the aligned size and clear the unused tail before pinning the
response buffer.
Fixes:
|
||
|
|
d12168084c |
ksmbd: safely drain sessions during logoff
SMB3 multichannel allows requests for one session to run on multiple
connections. Wait for all channels bound to a session before freeing
shared session objects.
A deferred byte-range lock remains counted as a running request and only
wakes when its file closes. Wake blocked locks during the drain without
unpublishing or modifying their file objects. Synchronous CANCEL requests
must invoke their cancellation callback to wake pending operations, while
CHANGE_NOTIFY completion remains specific to the asynchronous path.
Serialize session teardown with channel registration and previous-session
cleanup, and use atomic work-state transitions so LOGOFF, CANCEL, and
connection teardown invoke cancellation callbacks only once.
Fixes:
|
||
|
|
db2267b27c |
ksmbd: fill in FileSysIdentifier in FS_POSIX_INFORMATION
smb2_get_info_filesystem() reports 56 bytes for FS_POSIX_INFORMATION,
that is the whole of FILE_SYSTEM_POSIX_INFO, but never assigns
FileSysIdentifier. Those eight bytes go to the client as they are found
in the response buffer.
The buffer is zeroed on allocation, so a standalone request leaks
nothing. A compound request can leak: the offset of the next response
is advanced by the length pinned for the previous one, so a reply that
was written into the buffer and then dropped in favour of the short
error response of smb2_set_err_rsp() stays there, and the next reply is
laid over it with only the header cleared.
Report the file system id statfs() returned, which is what the field is
for. FileSysIdentifier is __le64 and f_fsid is a pair of ints, so
assemble the value first, val[0] as the low half, and convert it on the
way out.
Fixes:
|
||
|
|
c0cd3fc682 |
ksmbd: initialize FileSystemControlFlags in FS_CONTROL_INFORMATION
smb2_get_info_filesystem() reports 48 bytes for FS_CONTROL_INFORMATION,
that is the whole of struct smb2_fs_control_info, but never assigns
FileSystemControlFlags. Those four bytes go to the client as they are
found in the response buffer.
The buffer is zeroed on allocation, so a standalone request leaks
nothing. A compound request can leak: the offset of the next response
is advanced by the length pinned for the previous one, so a reply that
was written into the buffer and then dropped in favour of the short
error response of smb2_set_err_rsp() stays there, and the next reply is
laid over it with only the header cleared.
ksmbd does not implement quota tracking, so report no control flags.
Fixes:
|
||
|
|
399aa12450 |
ksmbd: zero the FS_OBJECT_ID_INFORMATION buffer before filling it in
smb2_get_info_filesystem() reports 64 bytes for FS_OBJECT_ID_INFORMATION,
that is the whole of struct object_id_info, but writes only 46 of them:
- objid[] is 16 bytes, and when the volume UUID is not available only
sizeof(stfs.f_fsid) (8) bytes are copied into it;
- extended_info.version_string[] is STRING_LENGTH (28) bytes, and only
strlen("1.1.0") (5) bytes are copied into it.
The response buffer is zeroed on allocation (kvzalloc() in
smb2_allocate_rsp_buf()), so for a standalone request the remaining 31
bytes are zero. In a compound request they need not be. The offset of
the next response is advanced by the length pinned for the previous one,
so if a preceding command wrote its reply into the buffer and then
failed, smb2_set_err_rsp() pins only the short error response and the
next reply lands inside the area that has already been written. Only
the header is cleared there:
memset((char *)rsp_hdr, 0, sizeof(struct smb2_hdr) + 2);
The client then receives up to 31 bytes of a response it was not meant
to see, including one that failed with an access denied error.
Clear the structure before filling it in. As a side effect
version_string is now NUL terminated.
Fixes:
|
||
|
|
a518e63c37
|
ovl: return EINVAL instead of EIO in case of mismatched user_ns
The EIO was used to signal an internal error (commit |
||
|
|
a67632c8c2
|
cachefiles: Fix potential UAF/KASAN warning
Currently, trace_cachefiles_coherency() is being passed a pointer to a
__be64 lain over the coherency data in struct cachefiles_xattr so that it
can display the first 8 bytes. However, the data is of variable length and
could even be 0 bytes. This could lead to a UAF or KASAN warning.
Fix this by making sure the buffer has room for at least 8 bytes and that
those 8 bytes are pre-cleared.
Further, those bytes are not 8-byte aligned, so fix the tracepoint to
extract the data as four 2-byte words (they are 2-byte aligned) and
reassemble the __be64. The compiler will convert this into a single 8-byte
load where the CPU supports it.
Fixes:
|
||
|
|
e00827a4d0
|
netfs: Fix read progress reporting
For really big read RPC ops that span multiple folios, netfslib allows the
filesystem to give progress notifications to wake up the collector thread
to do a collection of folios that have now been fetched, even if the RPC is
still ongoing, thereby allowing the application to make progress.
This works by taking the current rreq->cleaned_to value (which indicates
which folios have been unlocked) and adding the stashed size of the next
folio to it. cleaned_to, however, is subject to 64-bit tearing on a 32-bit
arch.
Fix this by stashing the next progress notification point as a size_t
(which won't tear) to be added to rreq->start (which won't change), with
the collector thread calculating that from cleaned_to plus the next folio
size.
Further, however, if the folios are small, the collector thread gets
constantly woken up - which has a negative performance impact on the
system.
Fix that too by setting a minimum trigger of 256KiB or the size of the
folio at the front of the queue, whichever is larger. Note that this has
an issue that different subreqs have different need-to-be-cached
properties; this is solved by a preceding patch that marks the property on
the folios whilst issuing subreqs rather than when collecting them.
Also, make sure rreq->cleaned_to is initialised up front, along with
rreq->collected_to and stream->collected_to.
Fixes:
|
||
|
|
533203c418
|
netfs: Mark folios with COPY_TO_CACHE whilst issuing subreqs
Mark folios with NETFS_FOLIO_COPY_TO_CACHE whilst issuing subreqs rather than when collecting them. This means that the collector thread doesn't have to try and keep track of which subreqs contribute to which folios - and thus which folios will need to be copied to the cache because at least one byte wasn't in the cache. Instead, this is marked on the folios up front and the collector need only consider the folios. For PG_private_2-using filesystems, PG_private_2 is set instead of NETFS_FOLIO_COPY_TO_CACHE, but otherwise it works the same. The NETFS_RREQ_COPY_TO_CACHE is replaced with NETFS_RREQ_CANCEL_CACHING, which is now set if caching fails somewhere, thereby causing the collection thread to cancel the copy-to-cache marks on the remaining folios. Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260827134304.2075713-9-dhowells@redhat.com Acked-by: Paulo Alcantara <pc@manguebit.org> cc: Paulo Alcantara (Red Hat) <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: netfs@lists.linux.dev cc: linux-mm@kvack.org cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org> |
||
|
|
fed0b33e6c
|
netfs: Fix readahead synchronisation issues by loading all folios upfront
There are some synchronisation issues that derive from the app thread
adding more folios to the rolling buffer whilst the collector thread is
looking at them or trying to clear them, such as determining the setting of
front_folio_order when the next folio hasn't been added yet,
The reason for the rolling buffer approach is that loading the buffer
upfront and then dropping all the refs just acquired is quite a slow
operation, and loading progressively allows some of the cost to be deferred
until after at least some of the I/O is started.
Instead, a better way is to load all the folios into the rolling buffer
upfront - and then drop the refs later, once the I/O is in progress. (Even
better would be for the refs not to be there at all.)
Fix this by changing the rolling buffer loader to load all the folios
selected by the VM for readahead upfront into the folio queue. The folio
queue is allocated a batch worth at a time as we don't know how many folios
are involved (the readahead_control struct, alas, has a page count, not a
folio count).
The folio refs acquired from readahead are then dropped in bulk once the
first subrequest is dispatched as it's quite a slow operation. The
collector waits for NETFS_RREQ_NEED_PUT_RA_REFS to be cleared so that it
doesn't unlock folios before the xarray has been scanned for them.
This simplifies the buffer handling later and isn't noticeably slower as
the xarray doesn't need to be modified and the folios are all already
pre-locked.
Fixes:
|
||
|
|
8fb45a9346
|
netfs: break unbuffered write when netfs_alloc_subrequest() fails
syzbot reported a null-ptr-deref below [1] following a fault injection in
netfs_alloc_subrequest(). [0]
When netfs_alloc_subrequest() fails, subreq is NULL.
Later, netfs_prepare_write() tries to initialize members of
subreq(e.g., source), the issue in [1] is triggered.
Let's handle the error of netfs_prepare_write() properly.
[0]
FAULT_INJECTION: forcing a failure.
name failslab, interval 1, probability 0, space 0, times 0
Call Trace:
netfs_alloc_subrequest+0x116/0x3f0
netfs_prepare_write+0x76/0x7b0
netfs_unbuffered_write+0x75c/0x2020
netfs_unbuffered_write_iter_locked+0x7d6/0xa80
netfs_unbuffered_write_iter+0x442/0x720
v9fs_file_write_iter+0xbf/0x100
vfs_write+0x6ac/0x1050
[1]
KASAN: null-ptr-deref in range [0x00000000000000a8-0x00000000000000af]
RIP: 0010:netfs_prepare_write+0xbc/0x7b0 fs/netfs/write_issue.c:173
Call Trace:
netfs_unbuffered_write+0x75c/0x2020 fs/netfs/direct_write.c:111
netfs_unbuffered_write_iter_locked+0x7d6/0xa80 fs/netfs/direct_write.c:290
netfs_unbuffered_write_iter+0x442/0x720 fs/netfs/direct_write.c:382
v9fs_file_write_iter+0xbf/0x100 fs/9p/vfs_file.c:409
new_sync_write fs/read_write.c:595 [inline]
Fixes:
|
||
|
|
3c30087e27
|
netfs: Fix subreq ref leak
Fix a subrequest ref leak in netfs_unbuffered_write() in the event that
subreq->io_iter ends up zero length during preparation.
Fixes:
|
||
|
|
741416a800
|
netfs: Fix i_size update for partial transfer
Fix netfs_unbuffered_write_done() to pass the amount written to
netfs_update_i_size() in the event of a partial transfer that ends in an
error.
That said, it might be better for the filesystem to mark the inode data as
invalid and recheck it in case something like a network error occurred that
prevented the reply from the server from being received.
Fixes:
|
||
|
|
0bfe2571a6
|
netfs: Fix error vs transferred passed to ->ki_complete()
Fix netfs_unbuffered_write_done() to pass the amount written to
->ki_complete() rather than the error in the event of a partially complete
transfer.
Fixes:
|
||
|
|
c753a33664
|
netfs: Fix unbuffered/DIO write partial transfer error return
Fix unbuffered/DIO write to return the amount of data transferred in
preference to an error if a partial transfer has been achieved, and to
prefer an error stashed in the request over the one returned by
netfs_unbuffered_write() (likely -EINTR or -ERESTARTSYS).
Fixes:
|
||
|
|
f18e8774f4
|
netfs: Fix uninitialized return value in netfs_unbuffered_write()
If preparation of the first subrequest fails,
netfs_unbuffered_write() exits its loop before ret is initialized. The
empty-iterator check can do the same.
For synchronous writes, netfs_unbuffered_write_iter_locked() may then
return an unrelated error instead of wreq->error. This is reachable
through CIFS if cifs_prepare_write() fails to reopen the file or obtain
credits.
Initialize ret to 0 so the caller returns wreq->error if no data was
written, or the number of bytes already written otherwise.
Found with Clang's -Wconditional-uninitialized.
Fixes:
|
||
|
|
b12e20c6ac
|
adfs: fix memory leak in sb->s_fs_info
Syzbot reported a memory leak in adfs during the mount process. The issue arises because the ownership of the allocated (struct adfs_sb_info) is transferred from the filesystem context to the superblock via sget_fc(). This function sets fc->s_fs_info to NULL after the transfer. The ADFS filesystem previously used the default kill_block_super for superblock destruction. This helper performs generic cleanup but does not free the private sb->s_fs_info data. Since fc->s_fs_info is set to NULL during the transfer, the standard context cleanup (adfs_free_fc) also skips freeing this memory. As a result, if the superblock is destroyed, the allocated struct adfs_sb_info is leaked. Fix this by implementing a custom .kill_sb callback (adfs_kill_sb) that explicitly frees sb->s_fs_info before invoking the generic kill_block_super. Reported-by: syzbot+1c70732df5fd4f0e4fbb@syzkaller.appspotmail.com Signed-off-by: Ahmet Eray Karadag <eraykrdg1@gmail.com> Link: https://patch.msgid.link/20251215031433.182205-2-eraykrdg1@gmail.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org> |
||
|
|
fe39cd9d48 |
cifs: don't update i_size in cifs_do_truncate without a cached handle
If find_writable_file() returns null, cifs_file_flush will return
0 without issuing set_file_size, and the outer 'if (!rc)' block
will set i_size to 0 before telling the server to truncate. If
the cifs_open() then fails, the inode will have size 0, while
the server file is unchanged.
Move the netfs_resize_file() and cifs_setsize() into the 'if
(cfile)', so they only run after a successful set_file_size.
In the no-handle else branch, evict stale pages with
truncate_inode_pages before the O_TRUNC open to dispose of old
cache pages, and let the open response set the i_size.
Fixes:
|
||
|
|
1dac61e2c2 |
smb: client: fix heap overflow in cifs_do_set_acl()
cifs_set_acl() validates ACL size using posix_acl_xattr_size():
4 + (count * 8) // 4-byte header + 8 bytes per ACE
cifs_do_set_acl() then calls posix_acl_to_cifs() to write the CIFS
wire format into the same buffer:
6 + (count * 10) // 6-byte header + 10 bytes per ACE
An ACL that passes the xattr-based check in cifs_set_acl() can
overflow the heap when posix_acl_to_cifs() writes the larger CIFS
format.
Validate the CIFS format size against the remaining buffer space and
USHRT_MAX before converting--data_count is __u16, so sizes above
USHRT_MAX truncate the on-wire packet length, causing the server to
apply a partial ACL. Replace MaxDataCount = 1000 with
min(CIFSMaxBufSize, USHRT_MAX).
Fixes:
|
||
|
|
6949939586 |
smb: client: fix multiuser mount with krb5
Customer reported that they could no longer mount their SMB shares
with multiuser mount option and krb5. Turned out that the client
wasn't duplicating username option when creating multiuser
connections, therefore failing to retrieve credentials as
cifs.upcall(8) couldn't find them in keytab.
Fix this by duplicating username option (if set) from original fs
context before creating multiuser connections with krb5.
Reproducer:
```
$ ktutil
ktutil: add_entry -password -p testuser -k 1 -e aes256-cts
Password for testuser@ZELDA.TEST:
ktutil: write_kt /etc/krb5.keytab
ktutil: quit
$ klist -ke
Keytab name: FILE:/etc/krb5.keytab
KVNO Principal
---- ----------------------------------------------------------------
1 testuser@ZELDA.TEST (aes256-cts-hmac-sha1-96)
$ mount.cifs //w22-root2/scratch /mnt/1 -o \
uid=1000,sec=krb5,username=testuser@ZELDA.TEST,multiuser
mount error(13): Permission denied
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) and
kernel log messages (dmesg)
```
Reported-by: Jacob Shivers <jshivers@redhat.com>
Fixes:
|
||
|
|
d83a21bb26 |
smb: client: transport: Fix debug printing in __release_mid()
Long time ago during upgrading printk():s to the respective pr_<level>()
calls one misconversion happened and nobody has noticed that. So,
previously printk(KERN_DEBUG) + printk() worked as one long debug print
since the trailing '\n' is only present in the followup printk() format
string. The culprit change missed that and split the message to two on
the different levels. Restore the original behaviour to make users be
less confused in the most likely never happen cases of partially getting
that message.
Fixes:
|
||
|
|
448ba0ae65 |
smb/client: invalidate fscache for fallocate range operations
smb3_zero_range(), smb3_punch_hole(), smb3_insert_range(), and
smb3_collapse_range() modify file contents through server-side range
operations. These operations discard the affected page cache, but leave
the FS-Cache cookie valid, so a later read may return data cached before
the range operation.
Fix this by invalidating FS-Cache after outstanding I/O has completed
and before modifying the file on the server.
Run the following as root on a CIFS mount with fsc enabled and an active
CacheFiles backend:
bash -c '
MNT=/mnt/cifs
FILE="$MNT/repro"
# Generate four 1 MiB random blocks: [A][B][C][D].
dd if=/dev/urandom of=/tmp/src bs=1M count=4 status=none
# Expected contents after zeroing B: [A][zero][C][D].
cp /tmp/src /tmp/expected
dd if=/dev/zero of=/tmp/expected bs=1M seek=1 count=1 \
conv=notrunc status=none
cp /tmp/src "$FILE"
# Populate FS-Cache, then discard the page cache.
sync
echo 1 > /proc/sys/vm/drop_caches
cat "$FILE" > /dev/null
sync
echo 1 > /proc/sys/vm/drop_caches
fallocate --zero-range -o 1M -l 1M "$FILE"
if cmp -s /tmp/expected "$FILE"; then
echo "readback: OK"
else
echo "readback: STALE DATA"
fi
'
Before this change, the readback differs from /tmp/expected:
readback: STALE DATA
After this change, it matches:
readback: OK
Fixes:
|
||
|
|
01261a6fa4 |
smb/client: fix stale page cache in insert/collapse range
smb3_insert_range() and smb3_collapse_range() use
truncate_pagecache_range() to invalidate the affected page cache.
However, if off or old_eof is not page-aligned, the boundary pages are
only partially zeroed and remain uptodate. As a result, the client may
return stale data after a successful insert/collapse range operation.
For example, with 4K pages:
page 0 page 1 page 2
0------4K 4K------8K 8K------12K
^ ^
off=2K old_eof=10K
Page 1 is removed from the page cache, while the boundary pages are
only partially zeroed. After COPYCHUNK moves the data on the server,
these cached pages may still return stale data.
This can be reproduced on a CIFS mount:
bash -c '
FILE=/mnt/scratch/repro
# Use a 6 KiB file so EOF is not page-aligned.
dd if=/dev/urandom of=/tmp/src bs=1K count=6 status=none
# Expected: a 4 KiB hole followed by the original data.
rm -f /tmp/expected
truncate -s 4K /tmp/expected
cat /tmp/src >> /tmp/expected
cp /tmp/src "$FILE"
# Prime the page cache before moving data on the server.
cat "$FILE" > /dev/null
fallocate --insert-range -o 0 -l 4K "$FILE"
if cmp -s /tmp/expected "$FILE"; then
echo "readback: OK"
else
echo "readback: STALE DATA"
fi
'
Fix this by writing back dirty data and discarding the page cache from
the start of the page containing off to EOF before moving data on the
server.
Fixes:
|
||
|
|
7811701d6a |
smb/client: fix integer truncation in collapse range
smb3_collapse_range() stores the ssize_t return value of
smb2_copychunk_range() in an int. A successful copy larger than
INT_MAX is truncated to a negative value and treated as an error.
Reproducer:
MNT=/mnt/scratch
truncate -s 2056M "$MNT/file"
fallocate --collapse-range -o 1M -l 1M "$MNT/file"
Fix this by using __smb2_copychunk_range(), which reports success as
zero instead of returning the copied byte count.
Before this change, the reproducer fails with:
fallocate: fallocate failed: Success
and the file size remains unchanged at 2056 MiB. After this change, the
reproducer succeeds and the file size becomes the expected 2055 MiB.
Fixes:
|
||
|
|
0923ae9f23 |
smb/client: fix data corruption in emulated insert range
smb3_insert_range() shifts [off, EOF) right with COPYCHUNK, copying from
low to high offsets. When the ranges overlap, the copy can overwrite
source data that has not yet been copied. For a 1 MiB insert at offset 0:
offset: 0 1M 2M 3M 4M 5M
before: | A | B | C | D |
expected: | hole | A | B | C | D |
current: | hole | A | A | A | A | (corrupted)
Let x be the insertion offset, L the total length to move, delta the
insert length, and C the normal chunk size allowed by the server.
Insert range maps
[x, x + L) -> [x + delta, x + delta + L).
When delta >= L, the complete source and target ranges are disjoint, so
the normal copy order and chunk size are safe:
offset: 0 4 8 12 16 20 24 28 32
source: [--S0--][--S1--][--S2--][--S3--]
target: [--T0--][--T1--][--T2--][--T3--]
When delta < L, the complete source and target ranges overlap, so the
copy must proceed from EOF backwards. There are two subcases.
If delta >= C, each corresponding source and target chunk is disjoint.
The 1 MiB example has L = 4 MiB and delta = C = 1 MiB:
offset: 0 1M 2M 3M 4M 5M
source: [--S0--][--S1--][--S2--][--S3--]
target: [--T0--][--T1--][--T2--][--T3--]
Copying S0 from [0, 1M) to [1M, 2M) overwrites S1 before it is copied.
Processing chunks from EOF backwards prevents this inter-chunk
overwrite.
If delta < C, the source and target ranges of a normal chunk also
overlap. For example, with L = 16, delta = 2 and C = 4:
offset: 0 2 4 6 8 10 12 14 16 18
source: [--S0--][--S1--][--S2--][--S3--]
target: [--T0--][--T1--][--T2--][--T3--]
Here S0 and T0 overlap over [2,4), S1 and T1 over [6,8), and so on.
Backward ordering cannot control how the server copies bytes inside one
descriptor, so the chunk size must be limited to delta.
Fix this by copying overlapping right shifts from EOF backwards. Limit
the chunk size to delta when delta < C so that each chunk's source and
target ranges do not overlap. Using larger chunks would require a way to
identify servers that safely handle overlapping COPYCHUNK descriptors.
Therefore:
delta >= L:
keep the normal copy order and chunk size
delta < L:
delta >= C: copy backwards and keep the normal chunk size
delta < C: copy backwards and limit the chunk size to delta
Only the delta < C subcase requires reducing the chunk size for data
integrity.
Reproducer:
bash -c '
MNT=/mnt/scratch
# Generate four 1 MiB random blocks: [A][B][C][D].
dd if=/dev/urandom of=/tmp/src bs=1M count=4 status=none
# With C = 1 MiB, test delta = C and delta < C.
for delta in 1M 1K; do
truncate -s 0 /tmp/expected
truncate -s "$delta" /tmp/expected
cat /tmp/src >> /tmp/expected
cp /tmp/src "$MNT/file"
fallocate --insert-range -o 0 -l "$delta" "$MNT/file"
if cmp -s /tmp/expected "$MNT/file"; then
echo "delta=$delta: OK"
else
echo "delta=$delta: CORRUPTED"
fi
done
'
The corruption reproduces with Samba and ksmbd, while Windows handles
the overlapping COPYCHUNK ranges safely.
The 1 MiB case tests delta >= C, while the 1 KiB case tests delta < C.
Before this change, the reproducer reports:
delta=1M: CORRUPTED
delta=1K: CORRUPTED
After this change, it passes against both ksmbd and Samba:
delta=1M: OK
delta=1K: OK
Fixes:
|
||
|
|
cd03ce4950 |
smb/client: mark file sparse before emulating insert range
The SMB client emulates FALLOC_FL_INSERT_RANGE with SET_EOF, COPYCHUNK
and SET_ZERO_DATA.
SET_ZERO_DATA creates a hole only when the file is sparse. On a
non-sparse file, it clears the inserted range but leaves its blocks
allocated, causing the extent count check in xfstests generic/064 to
fail.
Fix this by marking the file sparse before modifying it.
This patch produces the expected sparse extents in xfstests generic/064
only when the server-reported block size is compatible with the server's
deallocation granularity.
For ksmbd, the reported block size follows the backing filesystem,
and the test passes. For Samba, the test passes with a block size
matching the backend granularity, for example, 4 KiB on Btrfs, but not
with the default 1 KiB value. For Windows Server 2022, 4 KiB inserts do
not generate holes, while aligned inserts of 64 KiB or larger do.
Fixes:
|
||
|
|
88972e3575 |
smb/client: validate new EOF for zero range
When FALLOC_FL_ZERO_RANGE is used without FALLOC_FL_KEEP_SIZE,
smb3_zero_range() may extend EOF without checking RLIMIT_FSIZE, allowing
the file to grow beyond the caller's file-size limit.
Fix this by calling inode_newsize_ok() before sending the zero-range
request when the operation would extend EOF.
Reproducer, using a file on a CIFS mount:
bash -c '
FILE=/mnt/cifs/repro
trap "" SIGXFSZ
ulimit -f 3072
truncate -s 2M "$FILE"
fallocate --zero-range -o 0 -l 4M "$FILE"
echo "fallocate rc=$?"
stat -c "file size=%s" "$FILE"
'
Before this change, the operation succeeds despite the 3 MiB limit:
fallocate rc=0
file size=4194304
After this change, fallocate fails and leaves the file at 2 MiB.
Fixes:
|
||
|
|
1519dc88c8 |
smb/client: validate new EOF for insert range
smb3_insert_range() does not check if the new file size
(i_size + len) is valid. This allows FALLOC_FL_INSERT_RANGE to bypass
RLIMIT_FSIZE, exceed s_maxbytes, or produce a size outside the loff_t
range.
Use check_add_overflow() to calculate the new EOF. Validate it with
inode_newsize_ok() before modifying the file.
Reproducer, using a file on a CIFS mount:
bash -c '
FILE=/mnt/cifs/repro
trap "" SIGXFSZ
ulimit -f 3072 # RLIMIT_FSIZE = 3 MiB
# A regular write is stopped at 3 MiB.
dd if=/dev/zero of="$FILE" bs=1M count=4 status=none
stat -c "size after write: %s" "$FILE"
# Insert 2 MiB into a 2 MiB file.
truncate -s 2M "$FILE"
fallocate -i -o 0 -l 2M "$FILE"
stat -c "size after insert: %s" "$FILE"
'
Before this change, the regular write stops at the 3 MiB limit, but
insert range grows the file to 4 MiB:
dd: error writing '/mnt/cifs/repro': File too large
size after write: 3145728
size after insert: 4194304
After this change, insert range also fails at the limit and leaves the
2 MiB file unchanged:
dd: error writing '/mnt/cifs/repro': File too large
size after write: 3145728
fallocate: fallocate failed: File too large
size after insert: 2097152
Fixes:
|
||
|
|
034dd340b0 |
tracing fixes for v7.3:
- Fix error output of boot instance creation failure Currently if a boot instance creation fails, instead of printing out the name of the instance that failed, it prints "(null)". That is because it prints "cur_str" that had already been processed by strsep(). Print the saved name instead. While at it, print the error code of the failure. - Fix use-after-free for same named historgrams Histograms can be named so that they can be used in multiple events. But if the named histogram has a variable attached, the second event that uses the named histogram which duplicates it and needs to free the original after duplication leaves the old variable in place and still visible. If another histogram uses than variable, it will use the stale one which will try to reference the freed duplicate histogram and crash the kernel. Free the duplicate variables along with the duplicated histogram data. - Check return value of kthread_run() in event self test The events self tests uses a kthread for testing but does not check if it succeeded in creating a kthread. If the kthread creation were to fail, the code will still try to call kthread_stop() on the error returned. - Fix race between reading trace_pipe and updating subbuffer size If a user is reading the trace_pipe file at the same time they update the ring buffer sub-buffer size, can cause the trace_pipe read to read stale data. Add trace_access_lock() around updating the ring buffer sub-buffer size. - Fix eventfs_inode on failure path in creation of the events directory In the creation of the "events" directory, if after allocating the eventfs_inode a failure is detected, it calls cleanup_ei() which calls free_ei(). The free_ei() will test if eventfs_inode being freed has no children. It is a bug if it does. But on the failure case of the creation of the "events" directory, the children lists have not yet been initialized and the free will trigger a warning because list_empty() on an uninitialized list returns false. Move the initialization into init_ei() where it makes more sense and makes sure that a created eventfs_inode has its lists initialized upon creation. - Check return value of kthread_run() in ftrace direct sample code The sample code that shows how to use the ftrace direct calls does not test the return of kthread_run() to see if it succeeds. Return a failure if the kthread_run() doesn't succeed. - Clear user events state on fork in case of alloc failure On fork, the child gets a pointer to the parent's user events state. It makes a copy of it then updates the child's pointer to it. But if the allocation fails, the duplication function leaves the child with a pointer to its parent's descriptor. When the child cleans up its data, it will free the parent's descriptor while the parent is still using it. In the duplication function, set the child's user_event_mm to NULL before testing if the allocation succeeded, and when it exits it will not free the parent's descriptor. - Fix retry exhaustion in simple ring buffer reader swap simple_ring_buffer_swap_reader_page() starts with retry set to 8 and post-decrements it only after a failed link replacement. On the final attempt, a successful replacement leaves retry at zero, while a failed replacement leaves it at -1. But the check for success expects the retry value to be non-zero and exits with an error on zero. This is the opposite result. Fix it. - Fail nicely when the remote swap_reader_page() returns an error Currently, if the swap_reader_page() of a remote buffer fails, it triggers a WARN_ON_ONCE() and continues normally. Instead, have it exit with an error and a pr_warn() print instead of a full WARNING. -----BEGIN PGP SIGNATURE----- iIoEABYKADIWIQRRSw7ePDh/lE+zeZMp5XQQmuv6qgUCapOC3hQccm9zdGVkdEBn b29kbWlzLm9yZwAKCRAp5XQQmuv6qvjkAQCGVuyK980rwiBnfenWLpeB3QjfHA8B mV0mJSlGWm1t1gEA9WWzMGbp+OHeRV2xyA+xW7OS1S58VO9OIGrzXCGqbAM= =TrF5 -----END PGP SIGNATURE----- Merge tag 'trace-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace Pull tracing fixes from Steven Rostedt: - Fix error output of boot instance creation failure Currently if a boot instance creation fails, instead of printing out the name of the instance that failed, it prints "(null)". That is because it prints "cur_str" that had already been processed by strsep(). Print the saved name instead. While at it, print the error code of the failure. - Fix use-after-free for same named historgrams Histograms can be named so that they can be used in multiple events. But if the named histogram has a variable attached, the second event that uses the named histogram which duplicates it and needs to free the original after duplication leaves the old variable in place and still visible. If another histogram uses than variable, it will use the stale one which will try to reference the freed duplicate histogram and crash the kernel. Free the duplicate variables along with the duplicated histogram data. - Check return value of kthread_run() in event self test The events self tests uses a kthread for testing but does not check if it succeeded in creating a kthread. If the kthread creation were to fail, the code will still try to call kthread_stop() on the error returned. - Fix race between reading trace_pipe and updating subbuffer size If a user is reading the trace_pipe file at the same time they update the ring buffer sub-buffer size, can cause the trace_pipe read to read stale data. Add trace_access_lock() around updating the ring buffer sub-buffer size. - Fix eventfs_inode on failure path in creation of the events directory In the creation of the "events" directory, if after allocating the eventfs_inode a failure is detected, it calls cleanup_ei() which calls free_ei(). The free_ei() will test if eventfs_inode being freed has no children. It is a bug if it does. But on the failure case of the creation of the "events" directory, the children lists have not yet been initialized and the free will trigger a warning because list_empty() on an uninitialized list returns false. Move the initialization into init_ei() where it makes more sense and makes sure that a created eventfs_inode has its lists initialized upon creation. - Check return value of kthread_run() in ftrace direct sample code The sample code that shows how to use the ftrace direct calls does not test the return of kthread_run() to see if it succeeds. Return a failure if the kthread_run() doesn't succeed. - Clear user events state on fork in case of alloc failure On fork, the child gets a pointer to the parent's user events state. It makes a copy of it then updates the child's pointer to it. But if the allocation fails, the duplication function leaves the child with a pointer to its parent's descriptor. When the child cleans up its data, it will free the parent's descriptor while the parent is still using it. In the duplication function, set the child's user_event_mm to NULL before testing if the allocation succeeded, and when it exits it will not free the parent's descriptor. - Fix retry exhaustion in simple ring buffer reader swap simple_ring_buffer_swap_reader_page() starts with retry set to 8 and post-decrements it only after a failed link replacement. On the final attempt, a successful replacement leaves retry at zero, while a failed replacement leaves it at -1. But the check for success expects the retry value to be non-zero and exits with an error on zero. This is the opposite result. Fix it. - Fail nicely when the remote swap_reader_page() returns an error Currently, if the swap_reader_page() of a remote buffer fails, it triggers a WARN_ON_ONCE() and continues normally. Instead, have it exit with an error and a pr_warn() print instead of a full WARNING. * tag 'trace-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: ring-buffer: Stop remote reader update when page swap fails tracing: Fix retry exhaustion in simple ring buffer reader swap tracing/user_events: Clear copied tracing state before fork duplication samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-multi-modify samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-modify eventfs: Initialize ei->children and ei->list in init_ei() tracing: Fix use-after-free in trace_pipe read on sub-buffer order change tracing: Fix crash passing ERR_PTR to kthread_stop() tracing: Fix use-after-free with same-name named triggers tracing: Fix logged instance name on creation failure |
||
|
|
03c6ecc4b4 |
ntfs: fix FITRIM range alignment
ntfs_trim_fs() aligns the start of a free extent up to the device discard
granularity, but derives the discard length by aligning the original extent
length down. When the free extent start is not discard-aligned, adding that
length to the aligned start can extend the discard past the free extent and
into allocated clusters.
For example, with 4 KiB clusters and 32 KiB discard granularity, the free
extent [4 KiB, 36 KiB) becomes the discard range [32 KiB, 64 KiB), so
28 KiB beyond the free extent may be discarded.
Align the absolute end of the free extent down and derive the length from
the two aligned endpoints. Skip extents that contain no full discard unit.
Reproduced with a 4 KiB-cluster NTFS filesystem on scsi_debug configured
for 32 KiB discard granularity and read-zero-after-trim. Before this
change, FITRIM zeroed seven allocated 4 KiB clusters following an unaligned
32 KiB hole. With this change, the same data remains intact across FITRIM
and remount.
Fixes:
|
||
|
|
41a52ba4a5 |
ntfs: read WOF chunks outside the decompression lock
WOF decompression uses four module-global workspaces, one per compression
format, each with a static mutex. ntfs_read_wof_compressed_block() takes
that mutex once and holds it across the whole chunk loop, so both block
reads run inside it:
mutex_lock(ws->lock);
for each chunk {
parse_wof_chunk_table(..., ws->input, ...); /* reads disk */
ntfs_read_wof_chunk(..., ws->input, ...); /* reads disk */
decompress into ws->output;
}
mutex_unlock(ws->lock);
Readers of system-compressed files then serialise system-wide on the disk
waits, not just on the decompressor scratch the lock exists for. One
reader sleeping in submit_bio_wait() blocks all the rest.
The waits dominate. Reading an 8 MiB xpress4k file (2048 chunks at a 48%
compressed ratio, so 2048 acquisitions and 4096 block reads) and timing
ws->lock against the part of it spent in ntfs_bdev_read():
backing store held of that in I/O held after
virtio, host page cache 348 ms 321 ms (92%) 24.6 ms
virtio, throttled 100 MB/s 978 ms 948 ms (96%) 36.6 ms
The page-cache row is a lower bound, having no seek cost at all, and the
share still grows with slower storage because only the wait scales while
decompression stays near 26 ms.
The reads are inside the lock only because they land in ws->input, a
buffer shared through the workspace. Nothing else requires it:
parse_wof_chunk_table() and ntfs_read_wof_chunk() already take the buffer
as a parameter and both set *chunk_mem to a pointer inside it, so a
caller-owned buffer works unchanged.
Allocate that buffer per call, do both reads without the lock, and take
the lock only around decompression, which is the step needing ws->output
and ws->scratch. squashfs is arranged this way already: its
squashfs_decompress() is handed a bio that has been read, and locks only
for the CPU work.
Block reads are unchanged in number, they just no longer run under the
lock, and hold time stops tracking device speed.
This also unnests two per-inode locks from the global one, runlist->lock
taken by both reads and base_ni->mrec_lock taken for a resident stream.
A resident chunk needs no I/O at all, yet used to queue behind a reader
blocked in submit_bio_wait() and then take mrec_lock inside the global
mutex.
The buffer is 4608 bytes for xpress4k and at most 33280 for lzx32k. This
path already does GFP_NOFS allocations per call in ntfs_attr_iget(), and
in ntfs_attr_get_search_ctx() for a resident stream, so one more does not
change how it behaves under memory pressure. The workspace keeps output
and scratch, 4 KiB to 32 KiB and 6224 bytes (xpress) or 10240 (lzx), and
its "already allocated" test moves from ws->input to ws->output.
The lock is now taken per chunk rather than per call, which differs only
for a folio spanning several chunks: a few more uncontended mutex
operations in exchange for not holding it across the reads between them.
Verified under QEMU against an uncompressed copy of the same data, on an
8 MiB file and a 100000 byte one, the latter covering the tail chunk that
is not a full comp_unit.
Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
|
||
|
|
548e7bcd0c |
A wide variety of mostly CephFS fixes and cleanups, split between
changes that address edge cases (Sam, Xiubo, Matthew), efficiency improvements (Max) and AI-assisted hardening (Michael, Jeremy). One thing that stands out is Alex's change to how CephFS behaves in NEARFULL scenarios: the long-standing "make all writes synchronous" behavior has become opt-in. It was always somewhat controversial and doesn't make much sense for modern deployments; the new default is to continue normal operation (i.e. buffer writes as MDS allows, etc). The behavior in case the cluster reaches any FULL state remains the same as before. -----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEEydHwtzie9C7TfviiSn/eOAIR84sFAmqRz9QTHGlkcnlvbW92 QGdtYWlsLmNvbQAKCRBKf944AhHzi/63CACpEmwY/3lOZ4M0IQV2UJqSWzNNtUDI Hdq7hosk5gRXP/gG1bV63i935Ibe/Sp6Cb/XkTRcrPIxy/1eky8PDZN3knPlPocM TMAdLKUOzzpmehqORWdVsEGSYIXuIfVhrey30pfHVLQc86orTj7worDZydYl8r3L K6nAM8gfcT9l9Sd4jtquaT61kqCcjXKPANlvUtt8oqniMRdpL63GnFHaU33n3XTE 5Dalh4YHtIL4gTA6xZLbZqOq+99QbmmqlqlMiwFNtrfpVtPO7HWHrEy61mYrKW7U Nr7HRF6X+MeUngZVI5AgrH5K6HtlE0SeHZt2XSKuMKGMG+I4dcygUcSr =F8+z -----END PGP SIGNATURE----- Merge tag 'ceph-for-7.3-rc1' of https://github.com/ceph/ceph-client Pull ceph updates from Ilya Dryomov: "A wide variety of mostly CephFS fixes and cleanups, split between changes that address edge cases (Sam, Xiubo, Matthew), efficiency improvements (Max) and AI-assisted hardening (Michael, Jeremy). One thing that stands out is Alex's change to how CephFS behaves in NEARFULL scenarios: the long-standing "make all writes synchronous" behavior has become opt-in. It was always somewhat controversial and doesn't make much sense for modern deployments; the new default is to continue normal operation (i.e. buffer writes as MDS allows, etc). The behavior in case the cluster reaches any FULL state remains the same as before" * tag 'ceph-for-7.3-rc1' of https://github.com/ceph/ceph-client: (32 commits) ceph: force a cap message when a deferred revoke can't be acked immediately libceph: reject buckets with mismatched CRUSH ids ceph: reject export_targets ranks >= CEPH_MAX_MDS in mdsmap decode ceph: fix leaked inode reference on writeback abort at umount libceph: remove ceph_put_page_vector() libceph: validate banner payload length ceph: make nearfull sync writes opt-in ceph: do not repeat ceph_trim_dentries() if no progress possible ceph: drop mdsc->mutex before decoding the MDS reply ceph: fix UAF in check_new_map() on session freed during unlock ceph: fix UAF in __kick_flushing_caps() on cf entry freed during unlock ceph: pass inode pointer around instead of reloading it ceph: mark cap remove with RB_CLEAR_NODE() instead of setting ci=NULL ceph: add helper function ceph_cap_is_removed() ceph: make __ceph_remove_cap() static ceph: cap delegated inode count in ceph_parse_deleg_inos() ceph: bound num_export_targets array for mds info v2/v3 ceph: bound MDSCapAuth path and fs_name decode in handle_session() ceph: bound xattr value length in __build_xattrs() ceph: bound copied dentry name length in NFS export get_name ... |
||
|
|
ce727a090b |
This pull request contains updates for UBI and UBIFS:
UBI: - Support for a per-device wear-leveling threshold - Various fixes and cleanups of error paths - Correctly preserve torture flag up wear-leveling UBIFS: - Various fixes and cleanups of error paths and kernel-doc -----BEGIN PGP SIGNATURE----- iQJmBAABCABQFiEEdgfidid8lnn52cLTZvlZhesYu8EFAmqRnEsbFIAAAAAABAAO bWFudTIsMi41KzEuMTEsMiwyFhxyaWNoYXJkQHNpZ21hLXN0YXIuYXQACgkQZvlZ hesYu8HaKhAAuU11eCVhmQk9jpIdaOnFKwokE/PIj23SRz13jc7PWmFbAIHiaVt4 0p1Xd59kPfdFqsfBo6ZgSr+f0cQu2N1MjzZYSmaklG5iJk2+IuMOIvNdve/GFzNg X86J7yxLtrCq+ULNNgGv0m89G/uYoFP27Su0rAid4D2T5gYEOisXpPw5AhAL6+bS FLRMlt0QWCAtb66FmSeDgTW042NPoSCZNOsxF35X9hQ6RxvftB8mbggmTummmlgb K9Nsuwkarterq7JhS4X+RL6aZG7yDPfHVpdCDD6Ui4W0SP59W0oSokikm1myw6Yg 9NH67jUD03s0y/z3QaNiTVPuQXz5dpUyxGzK/FCT8y2aiycCDmwWF0VG8MVMhC0j TmNiuSWAljweaPSsgF176ISRG63++zwMGtz/JclVlkUwkVKYFbpEv5lcT0EzfCqh ahBlpM2aCLgJaYExd6LSVKEu0tT3+x+2MJDnRWcZM2OPMuL65IQw5V2lbdJN78Gb XFX6bfolhneptc2JwQKJx8E72iW7zuFovprTyS/J+TNcceFbfQTTcFt9EFZaXWnh +wiWm7rL7Xp9t8MA4Sc979oKFJMkAMl3Z6WTUHJWUZicX2hK+3OQaCVNO8LO/izu nPanrTeBnRiBKuAc5skQN5ywaAD3GgG/5ERWP/tdHkdsx34pcvuPnHQ= =+fCs -----END PGP SIGNATURE----- Merge tag 'ubifs-for-linus-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs Pull UBI and UBIFS updates from Richard Weinberger: "UBI: - Support for a per-device wear-leveling threshold - Various fixes and cleanups of error paths - Correctly preserve torture flag up wear-leveling UBIFS: - Various fixes and cleanups of error paths and kernel-doc" * tag 'ubifs-for-linus-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs: UBI: support per-device wear-leveling threshold UBI: fix two issues in the ubi.mtd MODULE_PARM_DESC mtd: ubi: Release device reference on busy detach ubi: Fix rollback for explicit UBI device numbers ubifs: fix out-of-bounds read in signature length check UBI: fastmap: Pass to_be_tortured when reusing old fastmap PEBs UBI: Preserve torture flag when rescheduling failed erasures ubifs: ubifs.h: clean up kernel-doc comments ubifs: key.h: use correct function parameter name ubifs: debug.h: fix kernel-doc struct prototypes |
||
|
|
115bd364ab |
f2fs-for-7.3-rc1
In this round, key enhancements focus on reducing inode management memory
overhead, introducing resizable tail sections with unified pinned allocation,
and boosting I/O throughput via parallel multi-device flushes and asynchronous
f2fs_write_end_io() execution. We also add dynamic device alias reservations to
allow on-the-fly space donation from user partitions.
Alongside these features, critical bug fixes resolve folio race conditions,
lingering dirty flags, dentry and block counter leaks, and potential deadloops
in f2fs_fsync_node_pages(). Additional stability patches address error-path
handling across symlink, sync, and rename/unlink operations, prevent pinned file
fragmentation, and correct segment migration and free section accounting in
free_segment_range.
Enhancement:
- reduce memory footprint of ino management
- support dynamic reserve/release for device aliasing
- issue multi-device flushes in parallel
- add a way to run f2fs_write_end_io() asynchronously
- support resizable tail section and unify pinned allocation
Bug fix:
- fix to pass folio->index to f2fs_sanity_check_node_footer()
- fix folio_nr_pages() race after put in large folio invalidate
- fix to clear dirty flag on folio in error path
- accurately adjust free_sections during free_segment_range
- fix to avoid potential deadloop in f2fs_fsync_node_pages()
- fix the error path in symlink, device alias in rename/unlink,
f2fs_sync_fs,
- fix to migrate all curseg types during free_segment_range
- fix to avoid pinfile fragment on fragment:{block, segment} mode
- fix valid block count leak on data block allocation failure
- fix dentry folio leak in find_in_level
- reject overlapping move range after len expansion
- fix some bugs related to file pinning, GC functions, i_size.
And, the series includes a number of minor bug fixes.
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEE00UqedjCtOrGVvQiQBSofoJIUNIFAmqPybMACgkQQBSofoJI
UNKp2g/+OP6XZi56hNTqscnKyKrDdVJnOcS/YOe7d1BR+070qmPTpyFjLgjng05K
exu55rz9vJ3DlpFLsjMEo60DRlDEc5rR4AqymMjqFJH9424ZlxPpdDn6ofCVT0Ck
D6RTf3y1HFSi4x7//gPQofR9y4MlDrH2Q7NPDriipqbymuNXEjrx/vdr2nq/kHUu
2lbf7QQs08qYiyDxQcxOFdCdxUTrsEW/tkYZiwgbU2nCJ/eG2R59amgtYJg3SlVt
xdrf+IaSS7kE5+mGCoBm0WooPpB507kHaoQpZYDj2uueFvEw7nFcSfOCXapOvg8U
wFkRR0F/rZ4+AW/u4n8Ye7N4a7WjWMTBwfR3WJ2j+arhfn87vJZK6LQQlYwq16l4
tRcQFcCrKsXHh5HY2OGj8DzTd40zryXujH566YioBCAXU312My1yFjeTJzjobbUW
TclkfMl689iTr9pqBhIjKT2tTvZFLROYSLk5UBNFNSfA4PtsAAhqlUrE1ck3AuTA
8kIjLmppfZEBqVuZCF0T1z9TXk0Bg0eM8qHbl/8SdDavmf1pF1BupLqchfdZp6Jr
4iV1weK4dzmCF6++YDsNlvnBGyTbhiFdN7C5cMlv89PTSTUQZ45Me6JmNwrRDqyU
MSTyiSSpI+3rAMO0h58PHi+QAOtM0f+S7C24ySkBBerBCbMTK6A=
=xQ77
-----END PGP SIGNATURE-----
Merge tag 'f2fs-for-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
Pull f2fs updates from Jaegeuk Kim:
"In this round, key enhancements focus on reducing inode management
memory overhead, introducing resizable tail sections with unified
pinned allocation, and boosting I/O throughput via parallel
multi-device flushes and asynchronous f2fs_write_end_io() execution.
We also add dynamic device alias reservations to allow on-the-fly
space donation from user partitions.
Alongside these features, critical bug fixes resolve folio race
conditions, lingering dirty flags, dentry and block counter leaks, and
potential deadloops in f2fs_fsync_node_pages(). Additional stability
patches address error-path handling across symlink, sync, and
rename/unlink operations, prevent pinned file fragmentation, and
correct segment migration and free section accounting in
free_segment_range.
Enhancements:
- reduce memory footprint of ino management
- support dynamic reserve/release for device aliasing
- issue multi-device flushes in parallel
- add a way to run f2fs_write_end_io() asynchronously
- support resizable tail section and unify pinned allocation
Bug fixes:
- fix to pass folio->index to f2fs_sanity_check_node_footer()
- fix folio_nr_pages() race after put in large folio invalidate
- fix to clear dirty flag on folio in error path
- accurately adjust free_sections during free_segment_range
- fix to avoid potential deadloop in f2fs_fsync_node_pages()
- fix the error path in symlink, device alias in rename/unlink,
f2fs_sync_fs
- fix to migrate all curseg types during free_segment_range
- fix to avoid pinfile fragment on fragment:{block, segment} mode
- fix valid block count leak on data block allocation failure
- fix dentry folio leak in find_in_level
- reject overlapping move range after len expansion
- fix some bugs related to file pinning, GC functions, i_size
And, the series includes a number of minor bug fixes"
* tag 'f2fs-for-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (51 commits)
f2fs: support resizable tail section and unify pinned allocation
f2fs: don't leave the hashed inode while it's unlinked
f2fs: accurately adjust free_sections during free_segment_range
f2fs: fix to avoid potential deadloop in f2fs_fsync_node_pages()
f2fs: use adjusted write range after f2fs_write_checks()
f2fs: fix to propagate error from f2fs_sync_fs()
f2fs: return symlink writeback errors
f2fs: fix error handling on device alias check in rename and unlink
f2fs: fix to reset all pinned status during fggc
f2fs: use f2fs_{down, up}_(read, write}_trace() for nat_tree_lock
f2fs: reduce memory footprint of ino management
f2fs: fix i_size when pinned fallocate partially fails
f2fs: fix to migrate all curseg types during free_segment_range
f2fs: avoid setting SBI_NEED_FSCK on transient resize failure
f2fs: fix to avoid pinfile fragment on fragment:{block, segment} mode
f2fs: cleanup w/ f2fs_need_rand_{blk, seg, seg_blk}
f2fs: fix to shrink gc_lock coverage in f2fs_gc_range()
f2fs: fix to reclaim space in f2fs_allocate_pinning_section()
f2fs: unify add/remove ino entry API for all ino types
f2fs: fix to zero post-EOF data when extending file size
...
|
||
|
|
18fbf5151d |
mm.git review status for linus..mm-stable
Everything: Total patches: 171 Reviews/patch: 1.83 Reviewed rate: 82% Excluding selftests: Total patches: 149 Reviews/patch: 1.77 Reviewed rate: 80% Excluding selftests and maple_tree: Total patches: 129 Reviews/patch: 1.99 Reviewed rate: 89% Summary of patch series in this merge: - "mm/rmap: index MAP_PRIVATE file-backed folios by anonymous pgoff" (Lorenzo Stoakes): Index MAP_PRIVATE file-backed folios by their anonymous page offset to resolve confusion around reverse mapping for zeroed and CoW'd file-backed memory. Use this new VMA anonymous page offset tracking to eliminate index conflicts and lay the foundation for scalable CoW performance improvements. - "promote mapped executable folios after first usage for MGLRU" (Baolin Wang): Make MGLRU's protection of mapped executable file folios more reliable. Follow the classical LRU's logic, promoting mapped executable file folios after their first usage to give executable code a better chance to stay in memory and improve workload performance. - "mm: vmscan: fix node reclaim ignoring swappiness parameter" (Ridong Chen): Fix per-node proactive reclaim interface's ignoring the swappiness parameter when CONFIG_MEMCG is disabled by consolidating sc_swappiness() into a single function that checks proactive_swappiness regardless of kernel configuration. - "mm/vmscan: reduce lru_lock contention via vmstat-derived scan-balance cost" (Usama Arif): Reduce lru_lock contention in the reclaim path by deriving scan-balance costs from vmstat counters rather than lock-acquired producer updates. Read and decay these cost signals on the reclaim side under a dedicated per-lruvec lock, reducing total LRU lock wait time by over 60% without impacting scan throughput. - "zram: fix zram issues reported by sashiko" (Sergey Senozhatsky): Fix two low-risk zram bugs which Sashiko spotted in drive-by review. - "Honor XA_FLAGS_ACCOUNT in xas_split_alloc() and charge to folio's memcg" (Zi Yan): Fix xas_split_alloc() by enabling target folio memcg charging during splits and adding the missing __GFP_ACCOUNT flag for proper XArray node memory accounting. - "selftests/mm: use pattern matching in .gitignore" (Pratyush Mallick): Replace hardcoded binary names in selftests/mm/.gitignore with a generic pattern-matching rule to automatically ignore generated test files and avoid manual updates when adding new tests. - "mm/page_ext: remove pgdat_page_ext_init()" (Sang-Heon Jeon): Make the incompatibility between FLATMEM and NUMA explicit in mm/Kconfig and remove the unused pgdat_page_ext_init() function. - "zram: fix zstd error paths and add parameter validation" (Haoqin Huang): Clean up zram compression backends by removing redundant error cleanup, adding parameter and dictionary validation, auto-prefixing algorithm error logs, and resetting parameters prior to reinitialization. - "zram: fix stale scan bounds after reinitialization" (Longlong Xia): Prevent out-of-bounds slot accesses during concurrent zram resets by moving table scan bound calculations under dev_lock in writeback_store() and read_block_state(). - "add anon mTHP collapse test cases" (Baolin Wang): Extend selftests helper functions to support arbitrary page orders and add new test cases and options for mTHP collapse in khugepaged. - "selftests/mm: Handle unsupported and transient test conditions" (Muhammad Usama Anjum): Update MM selftests to report a SKIP status instead of a failure when required kernel or filesystem features are unsupported, while adding retry logic for transient page migration errors. - "mm/zswap: Fixes and improves the zswap shrink" (Hao Jia): Fix the missing zswap global shrinker when CONFIG_MEMCG is disabled and extend shrink_memcg() to support batch writeback for improved writeback efficiency. - "alloc_tag: introduce IOCTL-based filtering for MAP" (Suren Baghdasaryan): Introduce an IOCTL-based binary interface for memory allocation profiling that enables kernel-side filtering before per-CPU counter aggregation. This eliminates the text-parsing overhead of /proc/allocinfo and provides up to a 20x speedup by transferring only filtered allocation data to userspace. - "better block swap batching and a different take on swap_ops v5" (Christoph Hellwig): Refactor block swap I/O to use swap_iocb for batching instead of single-bio requests and rebase the swap_ops interface, achieving faster swap throughput during kernel builds. - "mm: kmemleak: reduce transient false positives by confirming leaks" (Catalin Marinas): Reduce false-positive kmemleak reports by combining two kmemleak enhancements that add a second confirmation scan and a configurable minimum unreferenced scan count module parameter. - "mm: kmemleak: default min_unref_scans to 2 for verbose kernels" (Breno Leitao): Auto-scanning kernels can generate false-positive memory leak reports on single scans, so this patch defaults min_unref_scans to 2 when CONFIG_DEBUG_KMEMLEAK_VERBOSE is enabled to require a second confirming scan. - "swap_ops updates" (Christoph Hellwig): Batching I/O for synchronous swap devices causes performance regressions and filesystem-based swap suffers from double-indirection overhead. This series resolves both issues by reintroducing per-folio writes for synchronous swap and allowing filesystems to directly export their own swap_ops. - "mm/khugepaged: several cleanups" (Nico Pache): khugepaged accumulated redundant state-checking patterns and outdated comments following mTHP integration. Introduce dedicated helpers for PTE validation and event counting while refreshing the internal documentation. - "maple_tree: lock checking and clean ups" (Liam Howlett): Syzbot reports incorrectly blame memory management exit paths for locking bugs, maple tree erase operations risk allocation failures without gfp flags and internal documentation lacks clarity. Improve lock error detection, update docs, fix race and allocation edge cases and optimize erase allocations using a fallback to GFP_KERNEL | GFP_NOFAIL. -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQTTMBEPP41GrTpTJgfdBJ7gKXxAjgUCao9nJQAKCRDdBJ7gKXxA jk/9AQDlfevYJuSJmzAI8bt8ISG+/TfXMtIZC/MdbHqtQVYWPQD8Cvm3DUZsdGB/ Gloq/HBFuMPgE8p2pwUIthdgnTPNvAc= =c+Nb -----END PGP SIGNATURE----- Merge tag 'mm-stable-2026-08-26-15-22' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Pull more MM updates from Andrew Morton: - "mm/rmap: index MAP_PRIVATE file-backed folios by anonymous pgoff" (Lorenzo Stoakes) Index MAP_PRIVATE file-backed folios by their anonymous page offset to resolve confusion around reverse mapping for zeroed and CoW'd file-backed memory. Use this new VMA anonymous page offset tracking to eliminate index conflicts and lay the foundation for scalable CoW performance improvements. - "promote mapped executable folios after first usage for MGLRU" (Baolin Wang) Make MGLRU's protection of mapped executable file folios more reliable. Follow the classical LRU's logic, promoting mapped executable file folios after their first usage to give executable code a better chance to stay in memory and improve workload performance. - "mm: vmscan: fix node reclaim ignoring swappiness parameter" (Ridong Chen) Fix per-node proactive reclaim interface's ignoring the swappiness parameter when CONFIG_MEMCG is disabled by consolidating sc_swappiness() into a single function that checks proactive_swappiness regardless of kernel configuration. - "mm/vmscan: reduce lru_lock contention via vmstat-derived scan-balance cost" (Usama Arif) Reduce lru_lock contention in the reclaim path by deriving scan-balance costs from vmstat counters rather than lock-acquired producer updates. Read and decay these cost signals on the reclaim side under a dedicated per-lruvec lock, reducing total LRU lock wait time by over 60% without impacting scan throughput. - "zram: fix zram issues reported by sashiko" (Sergey Senozhatsky) Fix two low-risk zram bugs which Sashiko spotted in drive-by review. - "Honor XA_FLAGS_ACCOUNT in xas_split_alloc() and charge to folio's memcg" (Zi Yan) Fix xas_split_alloc() by enabling target folio memcg charging during splits and adding the missing __GFP_ACCOUNT flag for proper XArray node memory accounting. - "selftests/mm: use pattern matching in .gitignore" (Pratyush Mallick) Replace hardcoded binary names in selftests/mm/.gitignore with a generic pattern-matching rule to automatically ignore generated test files and avoid manual updates when adding new tests. - "mm/page_ext: remove pgdat_page_ext_init()" (Sang-Heon Jeon) Make the incompatibility between FLATMEM and NUMA explicit in mm/Kconfig and remove the unused pgdat_page_ext_init() function. - "zram: fix zstd error paths and add parameter validation" (Haoqin Huang) Clean up zram compression backends by removing redundant error cleanup, adding parameter and dictionary validation, auto-prefixing algorithm error logs, and resetting parameters prior to reinitialization. - "zram: fix stale scan bounds after reinitialization" (Longlong Xia) Prevent out-of-bounds slot accesses during concurrent zram resets by moving table scan bound calculations under dev_lock in writeback_store() and read_block_state(). - "add anon mTHP collapse test cases" (Baolin Wang) Extend selftests helper functions to support arbitrary page orders and add new test cases and options for mTHP collapse in khugepaged. - "selftests/mm: Handle unsupported and transient test conditions" (Muhammad Usama Anjum) Update MM selftests to report a SKIP status instead of a failure when required kernel or filesystem features are unsupported, while adding retry logic for transient page migration errors. - "mm/zswap: Fixes and improves the zswap shrink" (Hao Jia) Fix the missing zswap global shrinker when CONFIG_MEMCG is disabled and extend shrink_memcg() to support batch writeback for improved writeback efficiency. - "alloc_tag: introduce IOCTL-based filtering for MAP" (Suren Baghdasaryan) Introduce an IOCTL-based binary interface for memory allocation profiling that enables kernel-side filtering before per-CPU counter aggregation. This eliminates the text-parsing overhead of /proc/allocinfo and provides up to a 20x speedup by transferring only filtered allocation data to userspace. - "better block swap batching and a different take on swap_ops v5" (Christoph Hellwig) Refactor block swap I/O to use swap_iocb for batching instead of single-bio requests and rebase the swap_ops interface, achieving faster swap throughput during kernel builds. - "mm: kmemleak: reduce transient false positives by confirming leaks" (Catalin Marinas) Reduce false-positive kmemleak reports by combining two kmemleak enhancements that add a second confirmation scan and a configurable minimum unreferenced scan count module parameter. - "mm: kmemleak: default min_unref_scans to 2 for verbose kernels" (Breno Leitao) Auto-scanning kernels can generate false-positive memory leak reports on single scans, so this patch defaults min_unref_scans to 2 when CONFIG_DEBUG_KMEMLEAK_VERBOSE is enabled to require a second confirming scan. - "swap_ops updates" (Christoph Hellwig) Batching I/O for synchronous swap devices causes performance regressions and filesystem-based swap suffers from double-indirection overhead. This series resolves both issues by reintroducing per-folio writes for synchronous swap and allowing filesystems to directly export their own swap_ops. - "mm/khugepaged: several cleanups" (Nico Pache) khugepaged accumulated redundant state-checking patterns and outdated comments following mTHP integration. Introduce dedicated helpers for PTE validation and event counting while refreshing the internal documentation. - "maple_tree: lock checking and clean ups" (Liam Howlett) Syzbot reports incorrectly blame memory management exit paths for locking bugs, maple tree erase operations risk allocation failures without gfp flags and internal documentation lacks clarity. Improve lock error detection, update docs, fix race and allocation edge cases and optimize erase allocations using a fallback to GFP_KERNEL | GFP_NOFAIL. * tag 'mm-stable-2026-08-26-15-22' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (172 commits) selftests/proc: make proc-maps-race work with READ_IMPLIES_EXEC memcg: move LRU size accounting on reparenting instead of copying it mm/vmscan: fix comment logic in balance_pgdat maple_tree: add helper mas_make_walkable() maple_tree: avoid extra gap calculation maple_tree: fix argument name in header maple_tree: change two GFP flags in tests maple_tree: document erase and allocations better maple_tree: avoid mas_erase() and mtree_erase() failures maple_tree: document that erase may use GFP_KERNEL for allocations maple_tree: catch race in mas_alloc_cyclic() maple_tree: add bulk parent set helper maple_tree: micro optimisation of mas_wr_store_type() maple_tree: optimise mas_wr_node_store() when not in rcu mode maple_tree: use prefetched value in mas_wr_store_type() maple_tree: clarify comments on mas_nomem() maple_tree: drop MAPLE_ALLOC_SLOTS maple_tree: drop dead code from mas_extend_spanning_null() maple_tree: documentation fix maple_tree: add write lock checking with lockdep sequence numbers ... |
||
|
|
ac727d86fb |
ntfs: leave HasEA flag untouched on setxattr failure
In ntfs_set_ea(), the exit path unconditionally updates the HasEA
flag based on ea_info_qsize. When an error occurs before
ea_info_qsize is updated, NInoClearHasEA() hides existing on-disk
EAs until the inode is evicted.
Only update the flag on success.
Fixes:
|
||
|
|
67aded1da1 |
ntfs: fix race between fallocate and mmap reads
The fallocate implementation only takes invalidate_lock for punch hole,
collapse range, and insert range operations. For standard allocation modes
(mode == 0, FALLOC_FL_KEEP_SIZE), the lock is not held.
During ntfs_attr_fallocate(), new clusters are mapped to the runlist via
ntfs_attr_map_cluster() before being zeroed by ntfs_dio_zero_range(). This
creates a window where concurrent mmap page faults can read uninitialized
disk data.
Since mmap uses filemap_fault() which takes invalidate_lock in shared mode,
it can fault in pages during this window and expose old disk contents to
userspace. This is an information leak and data integrity issue.
Fix by taking invalidate_lock for all fallocate operations, not just for
punch/collapse/insert modes. This prevents concurrent page faults from
accessing unzeroed clusters during the allocation window.
Fixes:
|
||
|
|
acb1095fd2 |
ntfs: fix memmove overlap in ntfs_new_attr_flags
When the record shrinks while the payload offsets increase (e.g., enabling
compression reduces padding, making arec_size < old_arec_size, but the header
grows by 8 bytes), moving the name first can overwrite the old mapping_pairs
before they are copied. Move mapping_pairs first in this case.
Since mp_ofs is derived from name_ofs, they always change in the same
direction. Checking name_ofs alone is sufficient.
Fixes:
|
||
|
|
6faa235a64 |
ntfs: compute bi_sector in 512-byte units
bi_sector counts in 512 byte sectors and not in multiples of the
volume's sector size. Under "normal" circumstances (with 512 byte
sectors in NTFS) the current code works as is; however, when we have
a 4k sector size on the volume the current usage of NTFS_B_TO_SECTOR()
and ntfs_bytes_to_sector() end up converting to the number of 4k
sectors after mount.
Reads work today on 4k volumes as bdev-io.c as performing the shift
correctly inline. With writes, we end up with significant silent disk
corruption on these volumes.
This fixes changes to use the new ntfs_bytes_to_bio_sector() function
everywhere we're performing this calculation (including the existing
read path). For the change in inode.c it removes a dead code block
rather than updating.
Fixes:
|
||
|
|
c966d29e01 |
f2fs: support resizable tail section and unify pinned allocation
Currently, zoned block devices restrict pinned file allocations to conventional zones at the beginning of the storage (before first_seq_zone_segno), triggering range GC when conventional space is exhausted. On regular block devices, when preparing for future online filesystem resizing (e.g. partition shrinking), pinned files must not be allocated in the tail area that will be truncated, as pinned files cannot be relocated by GC. Specifying the resizable tail area size (in sections) allows uniform mount configuration across devices of different storage capacities. To support this, introduce a unified `pinned_area_max_secno` boundary abstraction in `f2fs_sb_info`: 1. Add `-o resizable_tail_secno=%u` mount option to specify the number of sections at the tail of the filesystem reserved for resizing. 2. In `f2fs_fill_super()`, initialize `sbi->pinned_area_max_secno` as: min(MAIN_SECS(sbi) - resizable_tail_sec, zoned_max_sec). 3. In `get_new_segment()`, restrict segment allocation for pinned files (`pinning == true`) to `0 .. sbi->pinned_area_max_secno - 1`. If no free section is available in the pinned area, return -EAGAIN. 4. In `f2fs_allocate_pinning_section()`, unify the range GC trigger to run `f2fs_gc_range()` up to `sbi->pinned_area_max_secno` whenever `sbi->pinned_area_max_secno < MAIN_SECS(sbi)` and allocation returns -EAGAIN. 5. Expose `/sys/fs/f2fs/<dev>/pinned_area_max_secno` as a read-only sysfs node. Signed-off-by: Daeho Jeong <daehojeong@google.com> Signed-off-by: Sunmin Jeong <s_min.jeong@samsung.com> Reviewed-by: Wenjie Qi <qiwenjie@xiaomi.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> |
||
|
|
53676a5e28 |
cifs: add revalidation on FSCTL failure in smb2_duplicate_extents()
smb2_duplicate_extents() has no handling for
FSCTL_DUPLICATE_EXTENTS_TO_FILE failure: when the FSCTL fails, local
inode metadata may be stale from the pre-extension or from concurrent
remote writes, but is never refreshed.
Force revalidation on FSCTL failure and use i_size_read() for the
pre-extension check.
Fixes:
|
||
|
|
73e3f07100 |
NFS client updates for Linux 7.3
Highlights include:
Stable fixes:
- SunRPC: Use-after-free fixes for the sunrpc client code
- NFSv4: Delegation hash table leak
- lockd: NULL dereference on lockowner allocation failure
- SunRPC: Fix a handshake completion race in the TLS code
- NFSv4.1/pNFS: Fix an error sign checking issue when deciding whether
the layout is still in use, or can be returned.
- NFSv4.1: Fix a layout segment leak in pnfs_layout_process()
Other bugfixes:
- SunRPC: Fix a missing NULL check in the rpcbind client
- SunRPC: annotate shared socket callbacks with READ_ONCE/WRITE_ONCE
- NFSv4: nfs_inode_set_delegation() error paths should return the delegation
- NFSv4: Use clear_and_wake_up_bit() in nfs_clear_invalid_mapping() and
the pNFS code.
- NFSv4: Fix the nfs4_alloc_client() error paths to free the IDR
allocation
- NFS: fix folio dereference before NULL check in nfs_inode_remove_request()
- NFS: Fix delayed delegation return
- NFSv4: Fix another state manager race with umount
- pNFS/blocklayout: Fix device leaks on parse failure
- pNFS: Avoid cancelling in-flight I/O during a layout recall if the
server doesn't require it
- NFSv4/flexfiles: report cancelled I/O as a layout error
- NFSv4/flexfiles: fix NULL dereference for NFSv4.0 data servers
- NFSv4: Fix incorrect argument passed to nfs4_delete_lease()
- NFSv3: Fix several symlink issues resulting from nfs_atomic_open_v23()
- NFSv4.1: Fix an uninitialised variable issue in the callback code
- NFSv4.2: fix LAYOUTSTATS send buffer exhaustion
Features and cleanups:
- NFSv4.2: Allow the server to specify that file data may not be cached
- NFS/localio: optimise I/O submission when when not doing memory reclaim
- NFS/localio: Remove duplicate wait code in nfs_local_commit
- NFSv4/flexfiles: support loosely coupled NFSv4.x data servers
- NFSv4/pnfs: key the data server cache on the NFS version
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQR8xgHcVzJNfOYElJo6EXfx2a6V0QUCao9SMwAKCRA6EXfx2a6V
0VxpAP9KSFbBnHU/DTq6zJ0xNeatZLBssrdkD1aPbHGsJPXukgEAgmo9tk0AgdJo
gxPeuVJIepg9PEIxI6jd6TxwpUV8NQI=
=k59o
-----END PGP SIGNATURE-----
Merge tag 'nfs-for-7.3-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust:
"Highlights include:
Stable fixes:
- Use-after-free fixes for the sunrpc client code
- Delegation hash table leak
- NULL dereference on lockowner allocation failure
- Fix a handshake completion race in the TLS code
- Fix an error sign checking issue when deciding whether the pNFS
layout is still in use, or can be returned
- Fix a layout segment leak in pnfs_layout_process()
Other bugfixes:
- Fix a missing NULL check in the rpcbind client
- annotate shared socket callbacks with READ_ONCE/WRITE_ONCE
- nfs_inode_set_delegation() error paths should return the delegation
- Use clear_and_wake_up_bit() in nfs_clear_invalid_mapping() and the
pNFS code.
- Fix the nfs4_alloc_client() error paths to free the IDR allocation
- fix folio dereference before NULL check in
nfs_inode_remove_request()
- Fix delayed delegation return
- Fix another state manager race with umount
- Fix device leaks on parse failure
- Avoid cancelling in-flight I/O during a layout recall if the server
doesn't require it
- flexfiles: report cancelled I/O as a layout error
- flexfiles: fix NULL dereference for NFSv4.0 data servers
- Fix incorrect argument passed to nfs4_delete_lease()
- Fix several symlink issues resulting from nfs_atomic_open_v23()
- Fix an uninitialised variable issue in the NFSv4.1 callback code
- fix LAYOUTSTATS send buffer exhaustion
Features and cleanups:
- NFSv4.2: Allow the server to specify that file data may not be cached
- localio: optimise I/O submission when when not doing memory reclaim
- localio: Remove duplicate wait code in nfs_local_commit
- flexfiles: support loosely coupled NFSv4.x data servers
- pNFS: key the data server cache on the NFS version"
* tag 'nfs-for-7.3-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (33 commits)
NFSv4.1: fix layout segment leak on the pnfs_layout_process() forget path
NFSv4/pnfs: key the data server cache on the NFS version
NFSv4.2: fix LAYOUTSTATS send buffer exhaustion
pNFS: Fix EBUSY check in pnfs_layout_need_return
NFSv4.1: zero referring call lists before decoding
nfs: fix ENXIO on O_CREAT open of existing symlink over NFSv3
SUNRPC: wait for in-flight client TLS handshake callback
NFSv4: Fix incorrect argument passed to nfs4_delete_lease() in nfs4_add_lease()
lockd: fix NULL dereference on lockowner allocation failure
NFS: fix delegation_hash_table leak when nfs4_server_common_setup() fails
NFSv4/flexfiles: support loosely coupled data servers
NFSv4/flexfiles: fix NULL dereference for NFSv4.0 data servers
NFSv4: pin the superblock for active state owners
sunrpc: fix use-after-free in __rpc_clnt_handle_event and __rpc_clnt_remove_pipedir
NFS/localio: issue commit inline when not in a memory-reclaim context
NFS/localio: remove dead FLUSH_SYNC handling from nfs_local_commit
NFS/localio: issue IO inline when not in a memory-reclaim context
NFS: Fix delayed delegation return list handling
NFS: Verify symlink inode before caching target
NFS: fix folio dereference before NULL check in nfs_inode_remove_request()
...
|
||
|
|
8fdf946445 |
ceph: force a cap message when a deferred revoke can't be acked immediately
When the MDS revokes capabilities, handle_cap_grant() normally guarantees a response by setting `CHECK_CAPS_FLUSH_FORCE` (see commit |
||
|
|
aedc9053d9 |
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.
Cc: stable@vger.kernel.org
Fixes:
|
||
|
|
c25aee9c63 |
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
writepages_finish() never runs and the claim is leaked.
redirty_page_for_writepage() -> folio_redirty_for_writepage() ->
filemap_dirty_folio() sets PG_dirty directly and does not go through
->dirty_folio, so ceph_dirty_folio() is not re-entered to rebalance it.
Because every subsequent writeback also fails the osd_stopping_blocker,
i_wrbuffer_ref never returns to 0, the ihold() is never dropped, and the
inode cannot be evicted:
VFS: Busy inodes after unmount of ceph
kernel BUG at fs/super.c:650!
Release the orphaned claim in the abort path before redirtying, via
ceph_undo_wrbuffer_claim(): detach the snap_context, drop the wrbuffer
reference (letting i_wrbuffer_ref reach 0 and iput() the inode), and drop
the snap_context reference -- i.e. do what writepages_finish() would have
done for these never-submitted folios.
Only the locked_pages entries are undone; folios still in the fbatch were
never dirty-cleared by this call (folio_clear_dirty_for_io() is the
ownership-transfer point, and a successful move NULLs the fbatch slot), so
they hold no claim this call owns.
Cc: stable@vger.kernel.org
Fixes:
|
||
|
|
2a2f98e17e |
libceph: remove ceph_put_page_vector()
ceph_put_page_vector() was paired with ceph_get_direct_page_vector(),
which was removed in commit
|
||
|
|
5f074d7f29 |
ceph: make nearfull sync writes opt-in
The kernel CephFS client has historically treated a cluster or pool NEARFULL condition as a request to force successful writes through generic_write_sync(). That effectively turns otherwise buffered writes into synchronous writes and can cause a severe throughput drop as soon as a single OSD or the file data pool crosses the nearfull threshold. On modern large clusters, NEARFULL is primarily an operator health signal rather than an immediate client-side capacity failure. Operators can still have substantial usable capacity while a cluster is rebalancing, splitting PGs, or expanding onto new devices. RBD, RGW and the userspace CephFS client do not impose this extra client-side sync-write throttle, so the kernel client behavior is surprising and operationally painful. Change the default behavior so NEARFULL no longer changes normal write-sync semantics. FULL and pool FULL still fail with -ENOSPC, and explicitly synchronous writes continue to be synced by generic_write_sync(). Add a nearfull_sync mount option for deployments that want the legacy backpressure behavior. When this option is set, successful writes are promoted to IOCB_DSYNC if the cluster or file data pool is marked NEARFULL, preserving the old behavior for conservative deployments. Link: https://tracker.ceph.com/issues/74849 Signed-off-by: Alex Markuze <amarkuze@redhat.com> Reviewed-by: Xiubo Li <xiubo.li@clyso.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> |
||
|
|
e7d7aa7b73 |
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
`false` (i.e. we have no intention of reclaiming dir leases),
__dir_lease_check() returned `TOUCH` for every valid lease. `TOUCH`
moves the dentry to the tail of the list and resets `di->time` via
__dentry_dir_lease_touch(), so a walk over N valid leases pointlessly
rewrote the list, refreshed the timestamps (preventing them from ever
aging out) and always drained `nr_to_scan`, guaranteeing the `-EAGAIN`
requeue.
Fix this in three steps:
- Return `KEEP` instead of `TOUCH` when `expire_dir_lease` is
`false`. If we are not going to reclaim the lease, leave it in
place instead of churning the list and resetting its timestamp; the
walk then terminates naturally (or via `STOP` at the first fresh
lease).
- Only return `-EAGAIN` from the first (dentry-lease) walk when something
was actually freed. A full batch that frees nothing means retrying
the same list immediately is futile; fall through to the dir-lease
walk instead.
- After both walks, bail out with success (0) when nothing was freed
and there is no cap pressure (`count==0`). There is no reason to
keep retrying when we are not over the cap limit and made no
progress.
Under real cap pressure (`count>0`) the reclaim path is unchanged and
still retries via `-EAGAIN`.
Without this patch, I saw 500 ceph_trim_dentries() calls per second on
our web servers. This is very visible in `/proc/lock_stat` (5 minute
capture):
class name con-bounces contentions waittime-min waittime-max waittime-total waittime-avg acq-bounces acquisitions holdtime-min holdtime-max holdtime-total holdtime-avg
&mdsc->dentry_list_lock: 126180 128218 0.04 8063.44 15986965.20 124.69 1573354
|
||
|
|
1319b97dfe |
ceph: drop mdsc->mutex before decoding the MDS reply
handle_reply() held `mdsc->mutex` across parse_reply_info(), i.e. across the full decode of the reply message. For large replies (a big readdir allocates and parses many dir_entries), this can take a while and blocks ceph_mdsc_submit_request() calls meanwhile. The decode does not need `mdsc->mutex`: parse_reply_info() mostly fills the request's `r_reply_info`. Create replies may also add delegated inode numbers to the session xarray, but that xarray is protected by its own lock and is not serialized by `mdsc->mutex` today. By the time we reach parse_reply_info(), all `mdsc->mutex`-protected state has already been updated under the lock (the request has either been unregistered (safe reply) or added to the session's unsafe list (unsafe reply)) and the request is pinned by the reference taken in lookup_get_request(). Drop `mdsc->mutex` before calling parse_reply_info() so reply decoding no longer blocks request submission. This only widens the existing unlocked window that already covers the heavier ceph_fill_trace() / ceph_readdir_prepopulate() processing, so no new races are introduced. Signed-off-by: Max Kellermann <max.kellermann@ionos.com> Reviewed-by: Xiubo Li <xiubo.li@clyso.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> |
||
|
|
ee611a7509 |
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 extra reference, another thread can acquire mdsc->mutex
during the unlock window, call __unregister_session() which drops the
last reference on s, and free it. The original thread then accesses
freed memory via s->s_mutex.
Fix by adding ceph_get_mds_session(s) before each mutex_unlock and
ceph_put_mds_session(s) after the corresponding mutex_lock, matching
the pattern already used in the forced-close path.
Race timeline (Path A):
Thread A (check_new_map) Thread B (another map update
holds mdsc->mutex or session teardown)
-------------------------- --------------------------
s = mdsc->sessions[i]
(refcount == 1, held only by
sessions[] array)
mutex_unlock(&mdsc->mutex)
---> acquires mdsc->mutex
__unregister_session(mdsc, s)
sessions[i] = NULL
ceph_put_mds_session(s)
refcount: 1 -> 0
kfree(s) <--- freed!
mutex_lock(&s->s_mutex)
UAF on freed s->s_mutex
Cc: stable@vger.kernel.org
Signed-off-by: Xiubo Li <xiubo.li@clyso.com>
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
|
||
|
|
7af4c4f013 |
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_flushing_caps() handle_cap_flush_ack()
----------------------- -----------------------
holds i_ceph_lock <---
iterates to cf (tid=10)
prepares FLUSH message
drops i_ceph_lock <---
__send_cap() ── FLUSH(tid=10)
MDS sends FLUSH_ACK(tid=10)
---> acquires i_ceph_lock
cf->tid(10) <= flush_tid(10),
detaches cf from i_cap_flush_list
drops i_ceph_lock
ceph_free_cap_flush(cf) <- frees it!
acquires i_ceph_lock <---
for-loop advances:
cf = list_next_entry(cf, i_list)
-- UAF on freed cf->i_list.next
The cf was just sent by __kick_flushing_caps itself via __send_cap().
The MDS may respond with FLUSH_ACK quickly enough that
handle_cap_flush_ack() frees cf before __kick_flushing_caps can
finish the iteration.
Fix by converting to a manual while loop: save the next pointer
under i_ceph_lock before dropping it, then use the saved pointer
after reacquiring, so the potentially-freed cf is never accessed again.
Cc: stable@vger.kernel.org
Signed-off-by: Xiubo Li <xiubo.li@clyso.com>
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
|
||
|
|
0cb1765957 |
ceph: pass inode pointer around instead of reloading it
All these functions already have a ceph_inode_info pointer, so let's use that instead of letting every function reload it from RAM (i.e. `ceph_cap.ci`). This eliminates several memory accesses. Signed-off-by: Max Kellermann <max.kellermann@ionos.com> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> |
||
|
|
af05588c97 |
ceph: mark cap remove with RB_CLEAR_NODE() instead of setting ci=NULL
__ceph_remove_cap() erases the ceph_cap object from the RB tree, thus it seems natural to use RB_CLEAR_NODE() / RB_EMPTY_NODE() for the removal check. Signed-off-by: Max Kellermann <max.kellermann@ionos.com> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> |
||
|
|
8619a36ff5 |
ceph: add helper function ceph_cap_is_removed()
Having it as a wrapper allows replacing the implementation, which the next patch will do. Signed-off-by: Max Kellermann <max.kellermann@ionos.com> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> |
||
|
|
6cd69ea0f0 |
ceph: make __ceph_remove_cap() static
It's only used from within caps.c. Signed-off-by: Max Kellermann <max.kellermann@ionos.com> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> |
||
|
|
4bd3158bd6 |
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 accumulate delegated inodes on the same session.
The original code bounded none of these and could spin the insert loop or
grow the xarray without limit.
Bound both dimensions with a single enforcement point. Track the number
of delegated inodes held by each MDS session in an atomic counter and
grow it only in ceph_insert_deleg_ino(), which uses atomic_add_unless()
to refuse to push the count past CEPH_MAX_DELEG_INOS. Because that helper
is the only place the counter grows, the per-session population can never
exceed the cap, so no separate per-session pre-check is needed. The
counter is decremented when async create consumes a delegated inode or
when an insert fails, incremented when a delegated inode is restored,
initialized with the session xarray, and reset when reconnect destroys
the xarray.
A per-session cap alone still lets one reply spin the insert loop on
duplicate ranges without growing the counter, so also cap the aggregate
interval length accepted from a single reply. Together these bound both
the loop trip count per reply and the xarray population across replies.
The cap is a fixed, client-chosen constant rather than a value derived
from the MDS. mds_client_prealloc_inos is a userspace MDS configuration
option; it is never sent to the kernel client on the wire, and a
server-supplied bound could not be trusted for a defensive limit in any
case. The constant is set well above that option's documented default of
1000 (a generous multiple), so legitimate refill behavior is unaffected
while the CPU and xarray memory a malformed delegation stream can consume
stays bounded.
Impact: a malicious or compromised Ceph MDS can no longer make a client
spin through an unbounded delegated-inode interval or grow one session's
delegated-inode xarray without limit.
Cc: stable@vger.kernel.org
Fixes:
|
||
|
|
a3eb169ee2 |
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 later export-targets loop
calls the unchecked ceph_decode_32() on out-of-bounds memory.
A kernel client processes CEPH_MSG_MDS_MAP from its monitor session
(net/ceph/mon_client.c dispatches it; fs/ceph/super.c routes it to
ceph_mdsc_handle_mdsmap(), which sets end to the front buffer bound and
calls ceph_mdsmap_decode()). A malicious or compromised monitor, or an
on-path attacker on an unsigned/unencrypted messenger session, can
therefore drive an out-of-bounds read in the client kernel; on x86_64
with KASAN it is reported as a slab-out-of-bounds read in
ceph_mdsmap_decode(). The decoded values land in the internal
info->export_targets[] array, so the consequence is a kernel
out-of-bounds read, not an information leak to the attacker.
Impact: a malicious or compromised Ceph monitor sending an MDS map with
a per-mds info version of 2 or 3 and an oversized num_export_targets
field triggers an out-of-bounds read in the CephFS client kernel.
Add a ceph_decode_need() for the export-targets array before advancing
the cursor, so the bound is enforced for every info_v >= 2, not only
info_v >= 4. This mirrors the count-then-need idiom already used for
m_data_pg_pools later in the same function.
Compute the export-targets byte count with size_mul() and reuse that
checked length when advancing the cursor, so the attacker-controlled
num_export_targets multiplication fails closed on overflow rather than
relying on the later kcalloc() guard.
Cc: stable@vger.kernel.org
Fixes:
|
||
|
|
77933e22ad |
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 enforced as an
upper bound. A length larger than the bytes remaining in the message
front makes ceph_decode_copy() read past the end of the front buffer.
The message front is a dedicated allocation (ceph_msg_new2() ->
kvmalloc), so the over-read runs off that object. A malicious or
compromised MDS can trigger this with the first post-connect message on
mount, with no client-side user interaction; under KASAN it is reported
as a slab-out-of-bounds read in handle_session().
Impact: a malicious MDS can force the kernel client to read up to 4 GiB
past the message front allocation during session setup, crashing the
client (out-of-bounds read).
Switch both copies to ceph_decode_copy_safe(), which performs the
ceph_decode_need() bounds check before the copy and branches to the
existing bad label, matching the rest of the decoder and the error path
that frees the partially decoded cap_auths array.
Cc: stable@vger.kernel.org
Fixes:
|
||
|
|
68d541754d |
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() on the following name length implicitly verifies
that the previous value did not run past the blob end. The final
attribute has no successor, so its decoded value length is never checked
against the blob bounds. A malicious or compromised metadata server can
set the last attribute's value length larger than the bytes actually
present in the blob.
The blob is a dedicated kvmalloc() allocation sized to the wire length
(ceph_buffer_new() in ceph_fill_inode()). __set_xattr() records the
oversized length in xattr->val_len verbatim, and a later getxattr(2) runs
memcpy(value, xattr->val, xattr->val_len) into a user-supplied buffer,
copying bytes past the end of the allocation back to user space.
Impact: a malicious metadata server discloses adjacent kernel heap bytes
to a local user via getxattr(2) on a CephFS file. Add the missing
ceph_decode_need() so an out-of-bounds value length on the final
attribute fails the decode and returns -EIO instead of being stored.
Cc: stable@vger.kernel.org
Fixes:
|
||
|
|
eff8013c5a |
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 path, a slab out-of-bounds write
reported by KASAN. Reachable when a CephFS mount is re-exported over NFS.
Add ceph_export_copy_name(), which rejects lengths above NAME_MAX with
-ENAMETOOLONG before the copy, and use it in both ceph_get_name() and
__get_snap_name().
Cc: stable@vger.kernel.org
Fixes:
|
||
|
|
d2a8d446a0 |
ceph: revalidate ki_pos for O_APPEND writes after cap acquisition
For O_APPEND writes, ki_pos is set to the current EOF via
generic_write_checks() after fetching i_size from the MDS. However,
ceph_get_caps() may need to wait for Fwx exclusive caps if the write
extends the file (endoff > i_max_size). While waiting for Fwx, the
previous Fwx holder (another client) may have already extended the
file. When the MDS grants us Fwx, the cap grant message updates the
local i_size, but ki_pos remains at the old EOF, causing the append
write to land at a stale offset and overwrite data from the other
client.
Fix by re-reading i_size_read(inode) after ceph_get_caps() returns.
At this point we hold Fwx exclusive caps, no other client can modify
the file, and i_size reflects the true EOF from the MDS cap grant.
No extra MDS round-trip is needed. Only adjust ki_pos when the EOF
has actually changed.
After adjusting ki_pos forward, the write range [pos, pos+count) may
now exceed the i_max_size that was validated by ceph_get_caps() for
the old range. Re-check against i_max_size and truncate the write
if necessary to stay within the MDS-granted limit.
Link: https://tracker.ceph.com/issues/7333
Fixes:
|
||
|
|
a354d7eaa1 |
ceph: fix use-after-dereference of NULL ci in __ceph_remove_cap()
The NULL check for "ci" in __ceph_remove_cap() was dead code because ci was dereferenced via &ci->netfs.inode before the check, and cap->session was dereferenced via session->s_mdsc->fsc->client even earlier. On a double-remove, both cap->ci and cap->session are set to NULL by the first call, so the second call would crash before ever reaching the guard. Move ci, session, cl, and inode initializations after the NULL check so that the early-return actually works. Signed-off-by: Xiubo Li <xiubo.li@clyso.com> Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> |
||
|
|
af59562a5b |
ceph: do not cache negative dentries for snapped directories
When a LOOKUP/LOOKUPSNAP in a snapped directory returns ENOENT without a trace, ceph_finish_lookup() creates a negative dentry via d_add(dentry, NULL). For live directories this is fine — the dentry naturally expires. But for snapped directories, ceph_d_revalidate() unconditionally trusts all cached dentries (valid = 1), so a negative dentry created by a transient error persists forever, hiding entries that genuinely exist in the snapshot. Only cache negative dentries for live (non-snapshotted) parent directories. For snapped parents, skip the negative dentry so that VFS retries the lookup on the next access. Since the conditions that trigger a negative dentry (MDS transient error, local ENOENT shortcut, or MDS null dentry lease) are all rare in snapped directories, the performance impact of this change is negligible. Link: https://tracker.ceph.com/issues/78529 Reported-by: Andras Pataki <apataki@flatironinstitute.org> Signed-off-by: Xiubo Li <xiubo.li@clyso.com> Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> |
||
|
|
699411a353 |
ceph: use GFP_KERNEL consistently in __ceph_pool_perm_get()
__ceph_pool_perm_get() has six allocations for building OSD STAT requests, five of which used GFP_NOFS and one (the page vector allocation) used GFP_KERNEL, making them inconsistent. The function is only called from ceph_try_get_caps() and __ceph_get_caps(), both of which are in the user I/O path (read, write, fallocate, mmap fault), not in the writeback path. There is no risk of recursive writeback, so GFP_NOFS is unnecessarily restrictive. Use GFP_KERNEL consistently for all six allocations. Signed-off-by: Xiubo Li <xiubo.li@clyso.com> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> |
||
|
|
9be23efacb |
ceph: use GFP_NOFS for cap flush allocation in writeback path
ceph_alloc_cap_flush() is called from ceph_writepages_start() inside
the writeback layer, where other allocations in the same path
(ceph_osdc_alloc_request, ceph_osdc_alloc_messages) already use
GFP_NOFS. A GFP_KERNEL allocation here can trigger direct reclaim
that recursively enters the filesystem writeback path:
ceph_writepages_start() // inode A writeback
ceph_alloc_cap_flush()
kmem_cache_alloc(..., GFP_KERNEL)
[direct reclaim]
try_to_free_pages()
shrink_slab()
super_cache_scan()
prune_icache_sb()
inode_lru_isolate()
iput() -> evict(inode_B)
[inode_B has dirty pages]
filemap_flush()
ceph_writepages_start() // re-enters writeback
ceph_alloc_cap_flush()
-> RECURSION / STACK OVERFLOW
All 11 callers of ceph_alloc_cap_flush() are in write or writeback
contexts: writepages (x2), write_iter, fallocate, copy_file_range,
setxattr, setattr, and page_mkwrite.
Signed-off-by: Xiubo Li <xiubo.li@clyso.com>
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Reviewed-by: Alex Markuze <amarkuze@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
|
||
|
|
ac9d69ae48 |
ceph: use detach_cap_releases() in ceph_send_cap_releases()
Eliminate some redundant code. Signed-off-by: Max Kellermann <max.kellermann@ionos.com> Reviewed-by: Xiubo Li <xiubo.li@clyso.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> |
||
|
|
e33752c851 |
ceph: skip __touch_cap() most of the time
__touch_cap() moves one capability to the end of the LRU list; this
list is sorted by access time for just one thing: ceph_trim_caps().
That function is supposed to discard the least-recently used
capabilities.
__touch_cap() is called extremely often - several times for every
system call, but ceph_trim_caps() is only called rarely.
__touch_cap() causes considerable lock contention on
`ceph_mds_session.s_cap_lock`; this is a /proc/lock_stat I captured on
one of our web servers for 5 minutes:
class name con-bounces contentions waittime-min waittime-max waittime-total waittime-avg acq-bounces acquisitions holdtime-min holdtime-max holdtime-total holdtime-avg
&s->s_cap_lock: 336304046 341686597 0.04 4905.76 418498578.76 1.22 892783632 1957814739 0.04 959.40 355752146.24 0.18
--------------
&s->s_cap_lock 339379730 [<00000000a2197200>] __ceph_caps_issued_mask+0x1bc/0x240
&s->s_cap_lock 1268054 [<00000000c96a24b7>] ceph_add_cap+0x234/0x3e0
&s->s_cap_lock 1021360 [<00000000aa76f996>] ceph_add_cap+0x108/0x3e0
&s->s_cap_lock 16042 [<0000000099463548>] __ceph_remove_cap+0x1f4/0x270
--------------
&s->s_cap_lock 338509619 [<00000000a2197200>] __ceph_caps_issued_mask+0x1bc/0x240
&s->s_cap_lock 1937864 [<00000000c96a24b7>] ceph_add_cap+0x234/0x3e0
&s->s_cap_lock
|
||
|
|
ad2d093781 |
ceph: Change system_unbound_wq with system_dfl_wq
system_wq (per-CPU) and system_unbound_wq (unbound) are the older
workqueue name, replaced by system_{percpu|dfl}_wq.
The new workqueues have been introduced by:
|
||
|
|
e939fc6a7b |
ceph: properly decrypt filenames in vmalloc() buffers
The fscrypt subsystem uses the scatterlist crypto API, inheriting its
requirement that any buffers are in the linear mapping region. However,
the messenger client uses kvmalloc() to create buffers for messages,
which will occasionally place those buffers in the vmalloc() region when
physical memory fragmentation doesn't permit a large enough kmalloc().
The various callers of ceph_fname_to_usr() directly pass (slices of) raw
messages from the MDS without considering that the messages may be in
vmalloc() buffers, resulting in oopses especially on non-x86 platforms
(see 'Closes:' for more details and a reproducer).
Make ceph_fname_to_usr() explicitly tolerant of vmalloc()-allocated
fname->ctext, fname->name, and/or oname->name buffers, using `tname`
(which, when non-null, must be a linear address; when null, is briefly
allocated as necessary) as a bounce buffer to avoid passing any
inappropriate addresses to fscrypt_fname_disk_to_usr().
Additionally change parse_reply_info_readdir() -- the only function to
supply its own `tname` -- to follow the new "tname must never come from
vmalloc()" rule by passing NULL when the message is not in the linear
region. Though this causes a per-dentry kmalloc()+kfree(), this overhead
exists only when processing the minority of messages that spill into
vmalloc(). My (crude) testing puts this at only about 1 in 8,000 readdir
messages. Still, if the overhead proves unreasonable in the future, it
is easy enough to mitigate: a future change could allocate a bounce
buffer in parse_reply_info_readdir() and use that as `tname` instead.
Cc: stable@vger.kernel.org # 888d33b208bd: ceph: pass fscrypt `tname` buffers directly
Cc: stable@vger.kernel.org
Fixes:
|
||
|
|
888d33b208 |
ceph: pass fscrypt tname buffers directly
ceph_fname_to_usr() needs a temporary buffer for some operations (currently only base64-decoding ciphertext) and it is convenient to allow the caller to specify this buffer to avoid a heap allocation, so it has a (nullable) `tname` argument. Until now, this argument was a `struct fscrypt_str`; however, this is unnecessary for two reasons: 1. `tname->len` isn't used anywhere: ceph_fname_to_usr() assumes a buffer large enough to hold the ciphertext, and parse_reply_info_readdir() -- the only caller to use tname -- doesn't set it. 2. While the `tname` parameter is documented "may be NULL," parse_reply_info_readdir() always passes it but with `tname->name` sometimes NULL in violation of the contract, indicating that the unnecessary container creates actual confusion. Therefore, change the type to `unsigned char *` and pass the buffer directly. Signed-off-by: Sam Edwards <CFSworks@gmail.com> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> |
||
|
|
4f49c3f8a5 |
ceph: Fix ERR_PTR(0) in ceph_mkdir()
When mkdir succeeds, ceph_mkdir() sets ret to ERR_PTR(0) which is
incorrect. It should return NULL instead for success.
Fixes:
|
||
|
|
323751a604 |
ntfs: reject invalid sectors_per_cluster in the boot sector
is_boot_sector_ntfs() checks the boot sector's sectors_per_cluster field
with a range test that rejects 0x81..0xf3 but accepts 0 and other
non-power-of-two counts. A zero value reaches parse_ntfs_boot_sector():
sectors_per_cluster_bits = ffs(sectors_per_cluster) - 1;
...
vol->cluster_size = vol->sector_size << sectors_per_cluster_bits;
ffs(0) is 0, so sectors_per_cluster_bits becomes (unsigned)-1 and the
shift is undefined:
UBSAN: shift-out-of-bounds in fs/ntfs/super.c:673:39
shift exponent 4294967295 is too large for 32-bit type 'int'
This change rejects any non-power-of-two value, since it feeds the
aforementioned shift via ffs() - 1, which only yields the correct shift for a
power of two.
Fixes:
|
||
|
|
c8504fc124 |
ntfs: bound $AttrDef table walk to the loaded table size
ntfs_attr_find_in_attrdef() walks the in-memory $AttrDef table, but the
loop condition bounds only the start of each entry, not the whole entry:
for (ad = vol->attrdef; (u8 *)ad - (u8 *)vol->attrdef <
vol->attrdef_size && ad->type; ++ad)
struct attr_def is 160 bytes; the guard reads ad->type at offset 128 and
the loop body reads further fields. vol->attrdef is kvzalloc(i_size),
where i_size is the on-disk $AttrDef data size, checked in
load_and_init_attrdef() only as 0 < i_size <= 0x7fffffff. A volume whose
$AttrDef data size is smaller than one entry (e.g. 120 bytes) makes the
read of ad->type run past the allocation. Creating a file reaches this
through ntfs_attr_size_bounds_check() and reads out of bounds:
BUG: KASAN: slab-out-of-bounds in ntfs_attr_find_in_attrdef+0x66/0xa0
Read of size 4 at addr ffff888005833280 by task init/1
ntfs_attr_find_in_attrdef
ntfs_attr_size_bounds_check
ntfs_attr_can_be_non_resident
ntfs_attr_add
Require the whole entry to lie within attrdef_size in the loop guard, and
reject at mount a $AttrDef too small to hold one attr_def entry.
Fixes:
|
||
|
|
a79899ca38 |
ntfs: fix undefined behavior in mft/index record size calculation
The boot sector validation allows clusters_per_mft_record and
clusters_per_index_record to range from 0xE1 (-31) to 0xF7 (-9) when
interpreted as signed values. When these are used as negative shift
counts in expressions like `1 << -clusters_per_mft_record`, values
like 0xE1 cause `1 << 31`, which shifts into the sign bit of a 32-bit
signed integer, resulting in undefined behavior.
Fix by using unsigned shift (1U << ...) instead of signed shift.
This prevents undefined behavior while preserving the full valid
range of negative values (-31 to -9) that may appear in NTFS boot
sectors.
The encoding scheme uses negative values to represent record sizes
smaller than cluster_size: -log2(record_size). Common values include
-10 (1024 bytes) for mft_record_size and -12 (4096 bytes) for
index_record_size.
Fixes:
|
||
|
|
607a947883 |
ntfs: treat any nonzero dio zero-range return as an error
ntfs_dio_zero_range() returns either 0 or a negative errno from
blkdev_issue_zeroout(); it never returns a positive value. The
zeroing failure check in ntfs_attr_fallocate() therefore never fired,
so a failed zeroing operation was silently ignored: the loop kept
going, the newly allocated clusters were folded into initialized_size
and the write could succeed leaving stale on-disk data.
Treat any nonzero return as an error and abort the allocation.
Fixes:
|
||
|
|
8d139e3635 |
ntfs: fix incorrect MFT record pointer passed to ntfs_attr_record_resize
ntfs_new_attr_flags() passes the wrong MFT record to ntfs_attr_record_resize().
When the attribute is in an extent record, ctx->mrec points to the extent
but the function receives the base record pointer m, causing incorrect
size calculations in memmove.
Fix by passing ctx->mrec (the actual MFT record containing the attribute)
instead of m (the base MFT record) to ntfs_attr_record_resize().
Fixes:
|
||
|
|
0e4c839905 |
ntfs: do not mark the volume clean in sync_fs when errors were recorded
ntfs_put_super() and the remount-read-only path both clear the dirty bit
only when NVolErrors(vol) is false. ntfs_sync_fs() clears it
unconditionally, so any sync() on a volume that recorded an error marks
that volume clean. A volume without this set is then seen as not needing
recovery and it does not run one, so whatever went wrong is never repaired.
This change skips resetting the dirty bit when there are volume errors.
Reproduced on a volume whose $MFTMirr does not match $MFT, which sets the
error flag while leaving the mount read-write: after a write and a sync,
the on-disk volume flags read 0x0000 with this driver and 0x0001 with the
guard in place.
Fixes:
|
||
|
|
5f2a22b36f |
ntfs: skip free cluster decrement when rollback fails
When the rollback in __ntfs_cluster_free() fails, the recursive
call returns a negative errno and the subsequent
ntfs_dec_free_clusters(vol, delta) subtracts that negative value,
adding bogus clusters to the counter on an already-failing volume.
Skip the decrement when the rollback failed.
Fixes:
|
||
|
|
be9e89ccb8 |
ntfs: only count successfully cleared runs when freeing clusters
ntfs_cluster_free_from_rl_nolock() adds a run's length to nr_freed
whenever the error bookkeeping condition is false, which includes
cases where ntfs_bitmap_clear_run() actually failed - e.g. a second
run failing with the same errno as an earlier one, or any failure
after a non-ENOMEM error was already recorded. Since a failed
ntfs_bitmap_clear_run() rolls back its partial modifications, no
bits were cleared for that run, yet its length still inflates
vol->free_clusters, corrupting statfs output and the allocator's
free space gate.
Only count runs whose bitmap clear succeeded.
Fixes:
|
||
|
|
cf06dcd572 |
ntfs: fix kmap_local leak in write_mft_record_nolock() error paths
write_mft_record_nolock() maps the MFT record folio with
kmap_local_folio(), but the pre_write_mst_fixup() and
bio_add_folio() failure paths jump to the error label without
unmapping it. kmap_local mappings are stack-ordered per task, so
leaking one corrupts the nesting for any outer mapping.
Unmap the folio on those error paths too.
Fixes:
|
||
|
|
ba1b61ddaa |
ntfs: return real error from ntfs_non_resident_attr_record_add()
ntfs_non_resident_attr_record_add() returns -1 at its put_err_out
label, which callers propagate as -EPERM to userspace.
Return the actual error code. Every path reaching the label has
err set to a negative errno.
Fixes:
|
||
|
|
8efe00b098 |
ntfs: preserve error code in ntfs_resident_attr_record_add()
ntfs_resident_attr_record_add() collapses every failure to -EIO at
its put_err_out label. This defeats the resident-to-non-resident
fallback in ntfs_attr_add(), which relies on seeing -ENOSPC to
convert the attribute when the MFT record has no room, and also
hides -EEXIST and -ENOMEM from callers.
Return the actual error code. Every path reaching the label has
err set to a negative errno.
Fixes:
|
||
|
|
ada7288019 |
ntfs: return -ERANGE for undersized xattr buffer
When the value buffer passed to getxattr(2) for system.dos_attrib,
system.ntfs_attrib or system.ntfs_attrib_be is smaller than the
attribute value, ntfs_getxattr() returns -ENODATA, which tells
userspace the attribute does not exist. The xattr API expects
-ERANGE in this case, and ntfs_get_ea() in the same file already
returns -ERANGE for regular EAs.
Fixes:
|
||
|
|
9692b1b4fc |
ntfs: propagate reparse index insertion failure
update_reparse_data() ignores the return value of
set_reparse_index(). When index insertion fails, the code removes
the just-written reparse data as cleanup but still returns 0, so
symlink(2) (and WSL special file creation) reports success while
no reparse data exists on disk. When there was no previous reparse
data (oldsize == 0), the failure was likewise silently ignored.
Propagate the error to the caller.
Fixes:
|
||
|
|
3d3de2aee1 |
ntfs: return DT_UNKNOWN on inode lookup failure in readdir
ntfs_reparse_tag_dt_types() returns PTR_ERR(vi) when ntfs_iget()
fails, but its return type is unsigned int and the caller passes
the value straight to dir_emit() as d_type. A stale or corrupt MFT
reference in a directory index thus makes readdir report a garbage
d_type value to userspace.
Return DT_UNKNOWN on lookup failure instead.
Fixes:
|
||
|
|
24c1a47f1e |
f2fs: don't leave the hashed inode while it's unlinked
f2fs_symlink() 1. f2fs_new_inode 2. f2fs_add_link 3. write_being|end to fill the symlink path 4. flush dirty pages and or checkpoint Step 4 is nice to succeed, which doesn't become a reason to roll back the created symlink. OTOH, if we get an error till step 3, don't leave its dentry and its inode. Reviewed-by: Chao Yu <chao@kernel.org> Reviewed-by: Wenjie Qi <qiwenjie@xiaomi.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> |
||
|
|
73ae59e975 |
Changes since last update:
- Fix up the EROFS_FS_ZIP_LZMA_DEFAULT_MAX_STREAMS default logic so that
"make savedefconfig" won't write the needless default value to the
defconfig file
- Add support for SEEK_{HOLE,DATA}, splice() as well as enable large
folios in inode_share mode
- Fix z_erofs_gbuf_growsize() after the previous buffer resizing fails
-----BEGIN PGP SIGNATURE-----
iQJFBAABCgAvFiEEQ0A6bDUS9Y+83NPFUXZn5Zlu5qoFAmqNu/kRHHhpYW5nQGtl
cm5lbC5vcmcACgkQUXZn5Zlu5qoMTA/8Cb7MRcm7eyCvTT1wyfgx6DSiOuYdITDW
6iQ/qRTnYDEO8FNVwqZJflLPO5pjIs/sucg69XvZg9cIP0gW4o3R5INJx+ZNZx0j
hnbPY8RNtIP0Z0rbt8Qes2cXORosZlqcdZvQFQgbmKx6jo72MLWMof7qM9jC8rOy
jMm9wipn7RjM5jN6sLGWMDleV+xfHOWT7cJzWL4qyJLgWWMp8vBMhuGfK46Cz/R4
wns+5gFanQAPmaWRJ8Wl0MIFBNhF49IGKRSxku8LYCmcnZMlnsL5TfQK/HP+d+o9
OLTK3M9zDm5VFbp18YAHNgZVUhZKZpaYC3PwmpY2t2/w2zjXVgQ1+dkXn5Iuho+y
IY7fc+D27E/QKUq7xz+H3i+0z7SW+nC4ErLxE6GQfpRLEV6GoYibkDuzrUH6+6sI
abJrLGwnE++ZXKBd3s2nspsn1Pq/ItyRdE4nsm5QZQbVbFDctZpG25gN0PM49DDV
jh6ByRMPkR5ZHVzdFhGsbT6KQyadEU/zr1AFy3UCOZ+JNv+Gs7HHI028vucbN3/x
SyX8wrt/D503+AZHLZdHp4y5BsdAXFp/qurHFY5JNMR0w7B8WmeV0q07XlBUle6v
vxQzQm920x5ZX9aGm+iYtMCWZyvdnTqp+eKHYwnyjifu6RbShFsMmpZsQ0+Du+NE
V/JvRUFV+ss=
=cqYR
-----END PGP SIGNATURE-----
Merge tag 'erofs-for-7.3-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs
Pull more erofs updates from Gao Xiang:
- Fix up the EROFS_FS_ZIP_LZMA_DEFAULT_MAX_STREAMS default logic so
that "make savedefconfig" won't write the needless default value to
the defconfig file
- Add support for SEEK_{HOLE,DATA}, splice() as well as enable large
folios in inode_share mode
- Fix z_erofs_gbuf_growsize() after the previous buffer resizing fails
* tag 'erofs-for-7.3-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs:
erofs: simplify z_erofs_gbuf_growsize()
erofs: skip sufficiently large global buffers when resizing
erofs: support large folios in inode_share mode
erofs: support splice() in inode_share mode
erofs: support SEEK_HOLE/SEEK_DATA in inode_share mode
erofs: Fix EROFS_FS_ZIP_LZMA_DEFAULT_MAX_STREAMS default logic
|
||
|
|
7f22f3a193 |
This contains 52 commits with improvements to compression support,
metadata handling, error propagation, and filesystem robustness.
New feature:
- Add optional read support for Windows System Compression (WOF).
Add CONFIG_NTFS_FS_WOF_COMPRESSION and support reading WOF-compressed
files through the NTFS page-read path. This includes parsing
REPARSE_TAG_WOF, handling resident and non-resident WOF metadata and
compressed chunks, and adding kernel-side XPRESS 4K/8K/16K and LZX 32K
decompressors. The codecs use a common transparent compression interface
shared with LZNT1. WOF support is read-only and disabled unless
explicitly enabled.
Other changes:
- Harden malformed filesystem handling and error paths.
Add bounds and consistency checks for mapping pairs, run lengths, MFT
locations, update-sequence offsets, non-resident attributes, compressed
attributes, index roots, and bitmap scans. Prevent out-of-bounds accesses
in decompression, MFT allocation, and index conversion paths, clean up MFT
mappings and attribute search contexts on failure, and propagate attribute
and inode initialization errors correctly.
- Improve compressed-file I/O path.
Fix compressed writes on large-page and highmem systems, reuse compression
contexts and output workspaces, avoid unnecessary reads for full-unit
overwrites, and submit one bio per compressed write unit. Write replacement
data before publishing the new mapping, correctly handle zero-filled
compressed blocks, and fix initialized-size and folio state updates after
compressed writes.
- Synchronize resident reads with MFT record updates.
- Validate the final EA stream size before modifying existing data, rewrite
the stream safely when replacing entries, restore the previous state when
metadata updates fail, and remove the EA attribute pair when the last
entry is deleted.
- Apply Windows filename restrictions only when windows_names is enabled.
- Allow index roots to relocate to extent MFT records when the base record
lacks sufficient space.
- Move non-resident attribute payload data before shrinking its record.
- Correct resident-to-non-resident conversion when compression or sparse
flags are enabled.
- Prepare file allocation and initialized-size updates before buffered or
direct I/O submission, and use pagecache_isize_extended() when extending
the file size.
- Fix highmem and page/folio access in compressed I/O paths by using the
correct local mappings and page helpers.
- Apply per-file $LXMOD permissions instead of mount masks when available,
and prevent unprivileged writes to reserved $LX* attributes.
- Update the NTFS maintainer mailing list.
- Four small cleanups.
-----BEGIN PGP SIGNATURE-----
iQJKBAABCgA0FiEE6NzKS6Uv/XAAGHgyZwv7A1FEIQgFAmqNZO8WHGxpbmtpbmpl
b25Aa2VybmVsLm9yZwAKCRBnC/sDUUQhCOOoD/9wqck6nOvUaCTRvcKbTEw2yVrR
C+S15hC/OuwqlxFHQQucav2NvCqwzuL/T/OBHycWi0NOycq+xYQQExs5wTms77R8
0a+lS5QS+evc8XM1IFOywiaetJQCpn6ivDimRKzZiuMJGPwdAVYY6dRX90WW1afl
fk9uxQHcy1Tvv7L1zvNbkr8vaycOH7LEWDukEe2XAXeZbQpumF8N0TETjH3oiNUK
NinDliRDisn0Z00qkV+DcGLQCYdVYgyJc9jW0lWT2Q2dd/o/NxfwZCrGXOSkzn1Y
6OXtMB36cQAxrW/lINwX0hSPj+YcMYQIi32nH3qyVC6+CcJ01OD5VU1aPtSsOqIX
viehEDBca7WJJq2AUBBUeAhK+Mq/exqNmm0UbMZKYikckkDrGDoYrnGMK4QAtkP5
EEduZRVy57VsRDV9gO/oNCMO3+VoAJ+iU27XFcHBxzpbsR0vmJWAjivSoRJducg0
nwZwUXfDxe6g4qFMVdd255y133uAsZ5G/lqPVFXEDiYfK/uCnKMH8O20HkzhYA75
b7sDbboRYhiXJhMKz08fKMgov4LvewgnC2wk0Farrvb719H6ELdcHooaIfBF4pkc
o1UStWnh/a6Sd4L5FCnVn4IBfiVkz9eDQzL0DKfhLfzVKcxyNmGStxrGSyUCZd6K
k1pRdpLI9Z2h6ALfhQ==
=pHcD
-----END PGP SIGNATURE-----
Merge tag 'ntfs-for-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/ntfs
Pull ntfs updates from Namjae Jeon:
"This contains improvements to compression support, metadata handling,
error propagation, and filesystem robustness.
New feature:
- Add optional read support for Windows System Compression (WOF)
Add CONFIG_NTFS_FS_WOF_COMPRESSION and support reading
WOF-compressed files through the NTFS page-read path. This includes
parsing REPARSE_TAG_WOF, handling resident and non-resident WOF
metadata and compressed chunks, and adding kernel-side XPRESS
4K/8K/16K and LZX 32K decompressors. The codecs use a common
transparent compression interface shared with LZNT1.
WOF support is read-only and disabled unless explicitly enabled.
Other changes:
- Harden malformed filesystem handling and error paths.
Add bounds and consistency checks for mapping pairs, run lengths,
MFT locations, update-sequence offsets, non-resident attributes,
compressed attributes, index roots, and bitmap scans. Prevent
out-of-bounds accesses in decompression, MFT allocation, and index
conversion paths, clean up MFT mappings and attribute search
contexts on failure, and propagate attribute and inode
initialization errors correctly.
- Improve compressed-file I/O path.
Fix compressed writes on large-page and highmem systems, reuse
compression contexts and output workspaces, avoid unnecessary reads
for full-unit overwrites, and submit one bio per compressed write
unit. Write replacement data before publishing the new mapping,
correctly handle zero-filled compressed blocks, and fix
initialized-size and folio state updates after compressed writes.
- Synchronize resident reads with MFT record updates.
- Validate the final EA stream size before modifying existing data,
rewrite the stream safely when replacing entries, restore the
previous state when metadata updates fail, and remove the EA
attribute pair when the last entry is deleted.
- Apply Windows filename restrictions only when windows_names is
enabled.
- Allow index roots to relocate to extent MFT records when the base
record lacks sufficient space.
- Move non-resident attribute payload data before shrinking its
record.
- Correct resident-to-non-resident conversion when compression or
sparse flags are enabled.
- Prepare file allocation and initialized-size updates before
buffered or direct I/O submission, and use
pagecache_isize_extended() when extending the file size.
- Fix highmem and page/folio access in compressed I/O paths by using
the correct local mappings and page helpers.
- Apply per-file $LXMOD permissions instead of mount masks when
available, and prevent unprivileged writes to reserved $LX*
attributes
- Update the NTFS maintainer mailing list
- Small cleanups"
* tag 'ntfs-for-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/ntfs: (52 commits)
ntfs: support resident WOF decompression
ntfs: add non-resident WOF decompression
ntfs: implement codec ops for LZX and XPRESS
ntfs: port lzx/xpress decompressors from ntfs-3g-system-compression
ntfs: return errors from inode initialization
ntfs: parse REPARSE_TAG_WOF
ntfs: return errors from ntfs_attr_readall
ntfs: add WOF compression config option
ntfs: define LZNT1 codec ops under transparent codec interface
ntfs: introduce transparent compression codec interface
ntfs: reject invalid empty mapping pairs
ntfs: fix resource leak in ntfs_new_attr_flags
ntfs: validate usa_ofs before preserving the update sequence number
ntfs: fix off-by-one page overflow in ntfs_decompress()
ntfs: do not update ctime when setxattr fails
ntfs: reject invalid MFT LCNs from boot sector
ntfs: serialize resident iomap reads with mrec_lock
ntfs: verify run length exceeding volume boundary
ntfs: allow index root relocation
ntfs: validate non-resident attribute offsets
...
|
||
|
|
8c963d1738 |
f2fs: accurately adjust free_sections during free_segment_range
In free_segment_range(), MAIN_SECS(sbi) is temporarily reduced by `secs`
to restrict block allocation to the safe remaining main area while valid
blocks in the truncated range are evacuated by GC.
However, FREE_I(sbi)->free_sections tracks the total number of free
sections across the whole filesystem. If any sections within the
truncated range were already free upon entering free_segment_range(),
failing to deduct them from free_sections causes the filesystem to
overestimate available free sections in the active, reduced main area.
This leads to inconsistent free section accounting during GC data
migration and can trigger unexpected allocation failures or assertion
errors when space is tight.
Fix this by calculating the number of already-free sections in the
truncated range, deducting them from free_sections upon entering
free_segment_range(), and restoring them on exit.
Fixes:
|
||
|
|
9cebfe6504 |
fuse update for 7.3
-----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQSQHSd0lITzzeNWNm3h3BK/laaZPAUCao1RzQAKCRDh3BK/laaZ PJ2EAP9dfslni4sFYqtXv/43Wk2iVwwdGRRSy5Tfoq8nCeNXpQEAygIv9BuJYpl6 DL861AOn/NfDBXpeU0vX4WQpTgtFIgc= =Av0t -----END PGP SIGNATURE----- Merge tag 'fuse-update-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse Pull fuse updates from Miklos Szeredi: - Improve performance of the io-uring transport by introducing buffer pools and zero-copy (Joanne) - Fix lots of bugs (Baokun Li) - Fix io-uring initialization issues (Joanne, Bernd) - More prep work for large folios (Joanne) - Don't limit buffered read to 128k (Jim Harris) - Fix zeroing of page end (dirtied with mmap) on file size extension (Jimmy Zuber) - Improve performance in certain cases with wake_up_sync() when queuing request (Xuewen Yan) - Misc fixes and cleanups (Xuewen Yan) * tag 'fuse-update-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse: (35 commits) fuse: zero the partial EOF page when extending a file io_uring: Add missing include for ITER_SOURCE and ITER_DEST fuse: Fix the condition to enable over-io-uring fuse: invalidate the correct range after O_APPEND direct write selftests/fuse: test post-EOF page zeroing when a file is extended fuse: wake one waiter per freed slot when raising max_background fuse: use min_not_zero() in fuse_init_server_timeout() fuse: copy request headers via a stack buffer for io-uring fuse: give wakeup hints to the scheduler for synchronous requests fuse: check for NULL root inode in fuse_fill_super_submount fuse: reject a duplicate fd= mount option cuse: wait for pending RCU callbacks on module exit fuse: fix invalidate lock leak on open O_TRUNC DAX failure fuse: fix invalidate lock leak on setattr writeback failure fuse: wait for FR_FINISHED on abort_on_kill to prevent use-after-free fuse: make dentry_tree_work static docs: fuse: document io-uring buffer pool and zero-copy uapi fuse: add zero-copy over io-uring fuse: support registered buffer pools in io-uring fuse: add io-uring buffer pools ... |
||
|
|
fe967191e5
|
fs: don't return -EINVAL for successful nested thaw
Commit |
||
|
|
08edfb34ee
|
ufs: do not treat unreadable directory blocks as empty
ufs_empty_dir() scans every directory block to decide whether a
directory is empty before rmdir() removes it. When ufs_get_folio()
cannot read or validate a block it returns an error pointer, and the
loop currently skips that block with continue and keeps scanning the
remaining blocks.
If none of the readable blocks hold an entry, the function returns 1
and the caller unlinks the directory. A directory whose contents live
in a block that cannot be read, for example because of an I/O error or
corrupted directory metadata, is therefore seen as empty and removed,
losing the entries it still holds.
Follow the ext2 behaviour and treat an unreadable block as a reason to
consider the directory not empty, so rmdir() fails instead of
discarding data that could not be verified.
Fixes:
|
||
|
|
c9d263be26
|
ufs: validate cylinder group metadata before caching it
ufs_read_cylinder() copies the cylinder group index and the rotor
positions straight from the on-disk group and caches them without any
check:
ucpi->c_cgx = fs32_to_cpu(sb, ucg->cg_cgx);
ucpi->c_rotor = fs32_to_cpu(sb, ucg->cg_rotor);
ucpi->c_frotor = fs32_to_cpu(sb, ucg->cg_frotor);
ucpi->c_irotor = fs32_to_cpu(sb, ucg->cg_irotor);
They are then used as indices during allocation and free:
- c_cgx indexes the cylinder summary array as
UFS_SB(sb)->fs_cs(ucpi->c_cgx), so a value past s_ncg writes a 32
bit count outside the s_csp allocation.
- c_frotor becomes a bitmap scan start, start = c_frotor >> 3, and
then length = ((s_fpg + 7) >> 3) - start. A start beyond the block
bitmap wraps the unsigned length to a huge value, so ubh_scanc()
walks far past the cylinder group buffers. c_irotor drives the
inode bitmap the same way.
A crafted image can set any of these freely, turning an ordinary
allocation into an out of bounds access.
Reject a cylinder group whose recorded index does not match the group
being read, or whose rotors fall outside the group, before the metadata
is cached. Valid filesystems keep cg_cgx equal to the group number and
the rotors within the group, so only malformed images are rejected.
Fixes:
|
||
|
|
55a4c98abb
|
ufs: create the root dentry after loading cylinder metadata
ufs_fill_super() installed sb->s_root before it loaded the cylinder
group structures for a writable mount:
sb->s_root = d_make_root(inode);
...
if (!sb_rdonly(sb))
if (!ufs_read_cylinder_structures(sb))
goto failed;
When ufs_read_cylinder_structures() failed, the error path freed the
in-core superblock information and set sb->s_fs_info to NULL while
sb->s_root stayed installed. get_tree_bdev() then reached
deactivate_locked_super(), and because s_root was present,
generic_shutdown_super() called sync_filesystem() and the put_super
operation. Both dereference UFS_SB(sb), which is now NULL, so a mount
that fails only while reading the cylinder groups oopses during
teardown. A crafted image whose first cylinder group cannot be read
reaches this path.
Load the cylinder group metadata first and create the root dentry last,
so the superblock is published to the VFS only once it is fully set up.
ufs_setup_cstotal() and ufs_read_cylinder_structures() take only the
super_block and do not use the root inode, so the reordering is safe.
Fixes:
|
||
|
|
ce366bfa82 |
f2fs: fix to avoid potential deadloop in f2fs_fsync_node_pages()
There is potential deadloop in race condition:
Thread A Thread B
- fsync
- f2fs_do_sync_file
- f2fs_fsync_node_pages
- last_fsync_dnode
- folio_get(last_folio)
- f2fs_setattr
- f2fs_truncate
- f2fs_truncate_blocks
- f2fs_do_truncate_blocks
- f2fs_truncate_inode_blocks
- truncate_dnode
- truncate_node
- invalidate_mapping_pages
- folio->mapping = NULL
- is_node_folio alwasy return false
- atomic && !marked is always true,
then goto retry
Cc: stable@kernel.org
Fixes:
|
||
|
|
22779ae817 |
mm/swap: move swap_ops into file systems for file system-based swap
Currently swap to and from file systems goes through two indirect calls between the swap ops and the swap_rw method. Reduce this by directly providing the swap_ops from the file system. For this refactor swap_fs_submit into a swap_fs_prepare_rw helper that initializes the iov_iter on the callers stack so that file systems can call it directly, and use that to initialize file system specific ops in the NFS and SMB clients, which then get passed to swap_fs_activate. Link: https://lore.kernel.org/20260723054622.3460249-4-hch@lst.de Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Chris Li <chrisl@kernel.org> Cc: Baoquan He <baoquan.he@linux.dev> Cc: Kairui Song <kasong@tencent.com> Cc: Kairui Song <ryncsn@gmail.com> Cc: Kemeng Shi <shikemeng@huaweicloud.com> Cc: Nhat Pham <nphamcs@gmail.com> Cc: Steve French <sfrench@samba.org> Cc: Usama Arif <usama.arif@linux.dev> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
0df74c1158 |
mm/swap: remove SWP_FS_OPS
Provide a swap_fs_activate helper that directly sets up swap_fs_ops, and a flag in struct swap_ops to indicate of NOFS swapping is allowed. Link: https://lore.kernel.org/20260713093350.2154226-7-hch@lst.de Signed-off-by: Christoph Hellwig <hch@lst.de> Cc: Baolin Wang <baolin.wang@linux.alibaba.com> Cc: Baoquan He <baoquan.he@linux.dev> Cc: Barry Song <baohua@kernel.org> Cc: Chris Li <chrisl@kernel.org> Cc: Kairui Song <kasong@tencent.com> Cc: Kemeng Shi <shikemeng@huaweicloud.com> Cc: Nhat Pham <nphamcs@gmail.com> Cc: Youngjun Park <youngjun.park@lge.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
32c9625638 |
tmpfs/ramfs: let memfd_create() work on nommu
Currently trying to use memfd_create() on nommu returns an error with errno set to EFBIG. The manpage memfd_create() doesn't have EFBIG as a possible error value. Doing some digging this is coming from 0 getting passed as newsize to ramfs_nommu_expand_for_mapping() and that getting into get_order() and there "The result is undefined if the size is 0". Whatever comes out of get_order() is then used in the following logic and that results in the EFBIG that causes the syscall to fail and the errno in userspace. If newsize is 0 there is nothing to do so just return. Roughly tested on m68k nommu by creating a process, creating an memfd, forking another process, mmap()ing the memfd in the child, writing into the mapping, then mmap()ing in the parent and checking that the right data is there. Link: https://lore.kernel.org/20260523130445.1101818-1-daniel@thingy.jp Signed-off-by: Daniel Palmer <daniel@thingy.jp> Acked-by: Lorenzo Stoakes <ljs@kernel.org> Cc: "Liam R. Howlett" <liam@infradead.org> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Christian Brauner <brauner@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
51943a18ad |
mm: provide vma_[flags_]is_cow_mapping() and remove is_cow_mapping()
All remaining callers of is_cow_mapping() are invoking it in the form of is_cow_mapping(vma->vm_flags) or an indirected version of this. Therefore, provide a helper - vma_is_cow_mapping() to directly test the VMA. Additionally provide a new helper vma_flags_is_cow_mapping() which performs the check using the new vma_flags_t type, and share this logic between vma_is_cow_mapping() and vma_desc_is_cow_mapping(). With these changes, no callers of is_cow_mapping() remain, so remove it. Also update the userland VMA tests to reflect the change. No functional change intended. [akpm@linux-foundation.org: fix kerneldoc comment typo, per Lorenzo] Link: https://lore.kernel.org/aob1goSSPH6sTN9y@gremlin Link: https://lore.kernel.org/20260813-b4-scalable-cow-virt-pgoff-v5-2-c21581c0c3c8@kernel.org Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Deucher <alexander.deucher@amd.com> Cc: Alexander Gordeev <agordeev@linux.ibm.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Alistair Popple <apopple@nvidia.com> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Baolin Wang <baolin.wang@linux.alibaba.com> Cc: Baoquan He <baoquan.he@linux.dev> Cc: Barry Song <baohua@kernel.org> Cc: Boris Brezillon <boris.brezillon@collabora.com> Cc: Byungchul Park <byungchul@sk.com> Cc: Chengming Zhou <chengming.zhou@linux.dev> Cc: Chris Li <chrisl@kernel.org> Cc: Christan König <christian.koenig@amd.com> Cc: Christian Borntraeger <borntraeger@linux.ibm.com> Cc: Claudio Imbrenda <imbrenda@linux.ibm.com> Cc: Dave Airlie <airlied@gmail.com> Cc: Dev Jain <dev.jain@arm.com> Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Gregory Price (Meta) <gourry@gourry.net> Cc: Harry Yoo <harry@kernel.org> Cc: Heiko Carstens <hca@linux.ibm.com> Cc: Huang Ray <Ray.Huang@amd.com> Cc: "Huang, Ying" <ying.huang@linux.alibaba.com> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jan Kara <jack@suse.cz> Cc: Jann Horn <jannh@google.com> Cc: Janosch Frank <frankja@linux.ibm.com> Cc: Jason Gunthorpe <jgg@ziepe.ca> Cc: Jiri Olsa <jolsa@kernel.org> Cc: John Hubbard <jhubbard@nvidia.com> Cc: Joshua Hahn <joshua.hahnjy@gmail.com> Cc: Kairui Song <kasong@tencent.com> Cc: Kees Cook <kees@kernel.org> Cc: Kemeng Shi <shikemeng@huaweicloud.com> Cc: Lance Yang <lance.yang@linux.dev> Cc: Liam R. Howlett <liam@infradead.org> Cc: Liviu Dudau <liviu.dudau@arm.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Marc Rutland <mark.rutland@arm.com> Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org> Cc: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Maxime Ripard <mripard@kernel.org> Cc: Miaohe Lin <linmiaohe@huawei.com> Cc: Michal Hocko <mhocko@suse.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Muchun Song <muchun.song@linux.dev> Cc: Namhyung kim <namhyung@kernel.org> Cc: Naoya Horiguchi <nao.horiguchi@gmail.com> Cc: Nhat Pham <nphamcs@gmail.com> Cc: Nico Pache <npache@redhat.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Oscar Salvador <osalvador@suse.de> Cc: Pedro Falcato <pfalcato@suse.de> Cc: Peter Xu <peterx@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rakie Kim <rakie.kim@sk.com> Cc: Rik van Riel <riel@surriel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Ryan Roberts <ryan.roberts@arm.com> Cc: Steven Price <steven.price@arm.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Sven Schnelle <svens@linux.ibm.com> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com> Cc: Thomas Zimemrmann <tzimmermann@suse.de> Cc: Vasily Gorbik <gor@linux.ibm.com> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: xu xin <xu.xin16@zte.com.cn> Cc: Zi Yan <ziy@nvidia.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
ce14fe4cd7 |
There are thirty-three client fixes:
- five sensitive data leak fixes (clear stack and heap cryptographic keys/hashes) - six file size and cache synchronization fixes (fscache cookie serialization and truncation handling) - seven protocol validation and buffer safety fixes (prevent OOB access and loff_t underflow) - six metadata and POSIX attribute fixes (proper hard-link counts and setuid/setgid stripping) - three DFS cache and unmount fixes (prevent target-hint UAF and unmount hangs) - six general client improvements (fix read request leaks, stats loops, handle servers that don't support O_TMPFILE) -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQTcqRusfSdYROJQwGkpVtNKoQNdYwUCaoy9dgAKCRApVtNKoQNd Y5zrAP9HRp0z9rLmezHzGoTnF+0WYnkE9xK9pqRDoIjflXPyDAD+IDYzBXTWJpoq O1+3OiuNGvoF+X46i8xE9voAbnCTDgM= =ETzr -----END PGP SIGNATURE----- Merge tag 'cifs-fixes-7.3-rc1' of https://git.manguebit.org/linux Pull smb client updates from Paulo Alcantara: - clear sensitive data after use (stack and heap cryptographic keys/hashes) - file size and cache synchronization fixes (fscache cookie serialization and truncation handling) - protocol validation and buffer safety fixes (prevent OOB access and loff_t underflow) - metadata and POSIX attribute fixes (proper hard-link counts and setuid/setgid stripping) - DFS cache and unmount fixes (prevent target-hint UAF and unmount hangs) - general client improvements (fix read request leaks, stats loops, handle servers that don't support O_TMPFILE) * tag 'cifs-fixes-7.3-rc1' of https://git.manguebit.org/linux: (33 commits) cifs: fix loff_t underflow in cifs_remap_file_range() when len == 0 smb: client: reject a tree connect response whose byte count is too small cifs: call pagecache_isize_extended() in cifs_setsize() when extending smb: client: fix copy-paste error in WSL EA length accounting for $LXDEV smb: client: remove redundant NULL check before kfree() smb: client: restore the data_offset bound in is_valid_oplock_break() cifs: clear tcon after cifsFileInfo_put() in cifs_file_set_size() smb: client: Avoid leaking sensitive data to the heap in connect.c smb: client: Clear sensitive stack data in smb1encrypt.c smb: client: Clear sensitive stack data in cifsencrypt.c smb: client: Clear sensitive stack and heap data in smb2ops.c smb: client: Clear sensitive stack data in smb2transport.c Revert "cifs: remove all cifs files before kill super" smb: client: fix use-before-check of ReparseDataLength in reparse_buf_ptr() smb: client: fix ALIGN() overflow in symlink_data() error context loop smb: client: simplify __build_path_from_dentry_optional_prefix() smb: client: fix UAF and buffer leak in cifs_check_trans2() for malformed secondary T2 smb: client: fix OOB read/write from unvalidated DataOffset in coalesce_t2() smb/client: decode reparse metadata using its payload type smb/client: preserve open info type across compound queries ... |
||
|
|
1704aaaf5d |
eventfs: Initialize ei->children and ei->list in init_ei()
eventfs_create_dir() allocates the eventfs_inode and initializes it with
init_ei(). But this does not initialize the eventfs_inode list_heads. If
the eventfs_create_dir() fails due to memory pressure, it will call
free_ei() before it initialized the lists, and that checks to make sure
the eventfs_inode has no children. But because the list wasn't
initialized, it will give a false warning.
Fix it by moving the list initialization into init_ei().
Cc: stable@vger.kernel.org
Fixes:
|
||
|
|
6c322f5cf7 |
cifs: fix loff_t underflow in cifs_remap_file_range() when len == 0
With len == 0 (clone to EOF), the effective length is computed as:
len = src_inode->i_size - off;
If off > i_size, this is a negative loff_t, corrupting the ByteCount
in the FSCTL_DUPLICATE_EXTENTS_TO_FILE request and inverting the range
in filemap_write_and_wait_range(). The existing off >= i_size check
fires only after the ioctl has already been sent.
Snapshot i_size_read() once for both the bounds check and the length
calculation, eliminating the TOCTOU and 32-bit torn-read risk. Reject
off > src_size with -EINVAL. Treat off == src_size as a no-op,
consistent with __generic_remap_file_range_prep().
Fixes:
|
||
|
|
65deb18359 |
smb: client: reject a tree connect response whose byte count is too small
CIFSTCon() bounds its strnlen() over the byte area with the server's
ByteCount minus two, which for ByteCount 0 or 1 goes negative as an int
and converts to a huge size_t. The later subtraction wraps the __u16
bytes_left, and that is what bounds cifs_strndup_from_utf16(): a bound of
up to 65535 against a ~16 KB cifs_req_poolp object runs off the end of the
slab object, and the bytes reach userspace through tcon->nativeFileSystem
in /proc/fs/cifs/DebugData.
Reject a byte area too small for what the parser consumes. Two bytes is
the least it can consume, and no conformant response carries fewer. The
new trace point is the 129th smb_eio_trace entry, which __mode(byte)
cannot represent, so the attribute goes with it.
Fixes:
|
||
|
|
c510edb973 |
cifs: call pagecache_isize_extended() in cifs_setsize() when extending
cifs_setsize() calls truncate_pagecache() but skips
pagecache_isize_extended() on extension. truncate_setsize() shows
the correct pattern:
i_size_write(inode, newsize);
if (newsize > oldsize)
pagecache_isize_extended(inode, oldsize, newsize);
truncate_pagecache(inode, newsize);
pagecache_isize_extended() zeroes the tail of the page straddling old
EOF. Without it, dirty bytes in that region can be written back to
the server, exposing stale data in the newly extended range.
Cc: stable@vger.kernel.org
Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
|
||
|
|
5d14030b46 |
smb: client: fix copy-paste error in WSL EA length accounting for $LXDEV
The LXDEV block in cifs_query_path_info() uses SMB2_WSL_XATTR_MODE_SIZE
(4) instead of SMB2_WSL_XATTR_DEV_SIZE (8), undercounting eas_len by 4
bytes per $LXDEV EA.
eas_len is used only as a zero/non-zero presence flag so there is no
current functional impact, but the value is incorrect and misleading.
Fixes: 97db41604555 ("smb: client: parse uid, gid, mode and dev from WSL reparse points")
Cc: stable@vger.kernel.org
Cc: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
|
||
|
|
019716ca26 |
smb: client: remove redundant NULL check before kfree()
kfree() safely handles NULL pointers, so the explicit NULL check before calling kfree() is unnecessary. This issue was reported by ifnullfree.cocci. Signed-off-by: Mohammad Shahid <mdshahid03@gmail.com> Signed-off-by: Paulo Alcantara <pc@manguebit.org> |
||
|
|
ba22f575de |
smb: client: restore the data_offset bound in is_valid_oplock_break()
Commit |
||
|
|
b96db32fed |
cifs: clear tcon after cifsFileInfo_put() in cifs_file_set_size()
When the else branch of cifs_file_set_size() finds a writable file handle
via find_writable_file(), it borrows tcon and server from the handle's
tlink, attempts the handle-based set_file_size() RPC, and then releases
the handle with cifsFileInfo_put().
If set_file_size() fails, execution falls through to the path-based
fallback, which reuses the borrowed tcon and server under the
"if (tcon == NULL)" guard. Since tcon is not NULL at that point, the
guard is skipped. If cifsFileInfo_put() dropped the last reference on a
tlink that was already removed from the tlink tree (TCON_LINK_IN_TREE
cleared, as happens during reconnection or session teardown),
cifs_put_tlink() will have freed tcon; the subsequent set_path_size()
call is then a use-after-free.
Setting tcon = NULL after cifsFileInfo_put() causes the existing guard
to take the cifs_sb_tlink() path, which acquires a fresh reference for
the path-based operation or fails cleanly if the session is gone.
Fixes:
|
||
|
|
111a2b8717 |
smb: client: Avoid leaking sensitive data to the heap in connect.c
TCP_Server_Info contains a preauth_sha_hash[] and a cryptkey[] array that might contain sensitive data. Thus free its memory with kfree_sensitive() to avoid that we are leaking this information to the heap. Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org> |
||
|
|
2f9af06e30 |
smb: client: Clear sensitive stack data in smb1encrypt.c
Make sure to not leak signature data via the stack, clear it with memzero_explicit() before leaving the function. To avoid that we have to introduce "goto"-cleanup here, we re-arrange the code a little bit (and drop the commented cifs_dump_mem debug code that looks like a leftover from very early days). Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org> |
||
|
|
1a6bd74a27 |
smb: client: Clear sensitive stack data in cifsencrypt.c
Make sure to not leak hash data via the stack, clear it with memzero_explicit() before leaving the function. Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org> |
||
|
|
55a1ad8413 |
smb: client: Clear sensitive stack and heap data in smb2ops.c
Make sure to not leak key-related data via the heap or the stack by using kfree_sensitive() or memzero_explicit() here. Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org> |
||
|
|
3d93986f68 |
smb: client: Clear sensitive stack data in smb2transport.c
Sensitive data like keys that are stored in stack-local arrays could be leaked via the stack to the calling functions. There is no known vulnerability for this right now, but it's good security style to explicitly zeroize this sensitive material as soon as possible to avoid that it could be exploited together with other bugs later. Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org> |
||
|
|
ce31ec06d3 |
Revert "cifs: remove all cifs files before kill super"
This reverts commit |
||
|
|
05f78e6cf3 |
smb: client: fix use-before-check of ReparseDataLength in reparse_buf_ptr()
reparse_buf_ptr() reads buf->ReparseDataLength before checking that
count covers the full fixed header:
buf = (struct reparse_data_buffer *)((u8 *)io + off);
len = sizeof(*buf); /* 8 bytes */
rdlen = le16_to_cpu(buf->ReparseDataLength); /* offset 4, 2 bytes */
if (count < len || count < rdlen + len) /* check comes after */
struct reparse_data_buffer has ReparseDataLength at offset 4. If a
server returns OutputCount < 6, the read at offset 4-5 reaches past
the end of the received data. The off+count bounds against iov_len
were already validated, but that does not protect against count being
smaller than sizeof(*buf).
Split the check: verify count >= sizeof(*buf) before reading
ReparseDataLength, then verify count covers the data region.
Fixes: a158bb66b137 ("smb: client: optimise reparse point querying")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
|
||
|
|
62656b024e |
smb: client: fix ALIGN() overflow in symlink_data() error context loop
The check added by commit |
||
|
|
3fffaa8a64 |
smb: client: simplify __build_path_from_dentry_optional_prefix()
Use the convenient 'strreplace()' to simplify '__build_path_from_dentry_optional_prefix()'. Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org> |
||
|
|
730d0bb195 |
smb: client: fix UAF and buffer leak in cifs_check_trans2() for malformed secondary T2
When a valid primary TRANSACT2 response has been received (mid->resp_buf
set, mid->multiRsp true) and a subsequent secondary response causes
cifs_check_trans2() to return false -- either because the SMB header is
invalid (malformed != 0) or because check2ndT2() rejects the PDU --
handle_mid() overwrites mid->resp_buf with the new buffer (leaking the
primary buffer) and, because mid->multiRsp is set, skips the
server->smallbuf/bigbuf NULL-out. When the user thread frees
mid->resp_buf, server->smallbuf or server->bigbuf is left dangling; the
demux thread reuses it for the next packet, resulting in a use-after-free.
Combine both early-exit conditions and, when mid->multiRsp is already
set, abort the pending transaction inline: set multiEnd, call
dequeue_mid() with malformed=true, and return true so handle_mid() exits
without touching mid->resp_buf or the server buffer pointers.
Fixes:
|
||
|
|
6343c1da56 |
smb: client: fix OOB read/write from unvalidated DataOffset in coalesce_t2()
coalesce_t2() computes data pointers directly from server-supplied
DataOffset fields with no validation against buffer bounds:
data_area_of_tgt = (char *)&pSMBt->hdr.Protocol +
get_unaligned_le16(&pSMBt->t2_rsp.DataOffset);
data_area_of_src = (char *)&pSMBs->hdr.Protocol +
get_unaligned_le16(&pSMBs->t2_rsp.DataOffset);
data_area_of_tgt += total_in_tgt;
...
memcpy(data_area_of_tgt, data_area_of_src, total_in_src);
A small DataOffset can push a pointer below the actual byte area,
overwriting header fields; a large one can push it past the buffer
end, causing out-of-bounds heap reads (source) or writes (target).
The BCC overflow guard does not prevent this: BCC reflects how much
data is present, while DataOffset controls where in the buffer it
starts.
The "validate target area" comment present since the function was
first written in 2005 was a placeholder that was never implemented.
Add lower- and upper-bound checks for both data pointers before the
memcpy, and before any target header fields are modified.
Fixes:
|
||
|
|
43549eb842 |
smb/client: decode reparse metadata using its payload type
cifs_open_info_data stores FILE_ALL_INFORMATION and SMB3 POSIX query
information in a union. reparse_info_to_fattr() selects a union member
from the mount mode, while several directory checks always read
fi.Attributes.
The metadata can instead come from an SMB2 CREATE response on a POSIX
mount, or from a POSIX query while processing a reparse point. In those
cases the mount mode and hard-coded fi accesses select the wrong union
member.
See the procedures below:
cifs_nt_open
smb2_open_file
SMB2_open
data->fi = SMB2 CREATE response
data->contains_posix_file_info = false
cifs_get_inode_info
reparse_info_to_fattr
if (tcon->posix_extensions) // true
smb311_posix_info_to_fattr
data->posix_fi // wrong union member
smb311_posix_get_fattr
smb2_query_path_info
smb2_compound_op
data->posix_fi = SMB3 POSIX query response
data->contains_posix_file_info = true
reparse_info_to_fattr
data->fi.Attributes // wrong union member
Add a common DOS attribute accessor and use contains_posix_file_info
both for attribute reads and for the final fattr conversion.
Signed-off-by: Ze Tan <tanze@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
|
||
|
|
9437f2113b |
smb/client: preserve open info type across compound queries
contains_posix_file_info describes the metadata stored in the
fi/posix_fi union. GET_REPARSE and QUERY_WSL_EA do not update that
union, so clearing the flag while processing those responses can make
POSIX metadata look like FILE_ALL_INFORMATION.
Set the flag when CREATE or a validated query response actually
populates the union, and leave it unchanged for auxiliary compound
operations. This also avoids changing the type when a query fails
before copying any metadata.
The issue can be reproduced against a Samba server with SMB3 UNIX
extensions enabled:
mount -t cifs //<server>/<share> /mnt/cifs \
-o vers=3.1.1,posix,reparse=nfs,actimeo=0
mkfifo /mnt/cifs/test-fifo
umount /mnt/cifs
mount -t cifs //<server>/<share> /mnt/cifs \
-o vers=3.1.1,posix,reparse=nfs,actimeo=0
stat -c '%F %s' /mnt/cifs/test-fifo
Before this change, stat reports "fifo 1024" although the server-side
EOF is zero. After this change, it reports "fifo 0".
Fixes:
|
||
|
|
ebdc1afb1e |
smb/client: mark missing nlink values as unknown
Several SMB1 fallback and open responses do not provide the hard link
count. The SMB2 create-only query fallback has the same limitation.
These paths currently leave a zero link count or synthesize a value of
one and then expose it as authoritative metadata.
Mark those results with unknown_nlink so existing inodes keep their
cached link count and new inodes receive the usual sane default.
This was tested against Samba with "server min protocol = NT1". Mount
the share using SMB1 with Unix extensions disabled:
mount -t cifs //<server>/<share> /mnt/cifs \
-o username=<user>,vers=1.0,nounix
Create three names for the same inode and cache its real link count:
TESTDIR=/mnt/cifs/nlink-repro-$$
mkdir "$TESTDIR"
touch "$TESTDIR/file1"
ln "$TESTDIR/file1" "$TESTDIR/file2"
ln "$TESTDIR/file1" "$TESTDIR/file3"
stat -c 'before open: %h' "$TESTDIR/file1"
Open the file and read the link count through the open descriptor:
exec 3<"$TESTDIR/file1"
stat -Lc 'after open: %h' /proc/$$/fd/3
exec 3<&-
Clean up the test files:
rm -f "$TESTDIR/file1" "$TESTDIR/file2" "$TESTDIR/file3"
rmdir "$TESTDIR"
Before this change, the two stat commands report 3 and 1 because the
SMB1 open response overwrites the known link count. With this change,
both commands report 3.
Signed-off-by: Ze Tan <tanze@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
|
||
|
|
48cab1fd57 |
cifs: fix clearing stats for fastest execution of each smb2 command
The code to clear the 'fastest_cmd' statistics has a typo that
repeatedly clears the stat for cmd 0, rather than iterating
through each cmd. Fix the typo (0->i).
Fixes:
|
||
|
|
3b2c5d35cf |
f2fs: use adjusted write range after f2fs_write_checks()
generic_write_checks() in f2fs_write_checks() can adjust iocb->ki_pos for append writes and truncate the iterator to limit the number of bytes to write. In f2fs_file_write_iter(), the pinned-file overwrite check currently uses the position and count saved before f2fs_write_checks(), so it can check a range different from the actual write range. The forced buffered I/O cleanup also uses orig_pos saved before f2fs_write_checks(). For O_APPEND writes, this can make the cleanup flush and invalidate the wrong page cache range. Move the pinned-file overwrite check after f2fs_write_checks() and use the adjusted iocb->ki_pos and iov_iter_count(from). Also save the adjusted write position and use it for the forced buffered I/O cleanup. Fixes: |
||
|
|
34b5c4a6e4 |
fuse: zero the partial EOF page when extending a file
Extending a fuse file past a non-page-aligned EOF does not zero the tail of the old last page. When that page is cached and has been mmap-dirtied beyond the old EOF, the now in-bounds tail is served to later reads as stale data rather than zeros, which violates POSIX file-extension semantics. Some file systems get this zeroing automatically at writeback time (block_write_full_folio() / iomap_writeback_handle_eof() zero the tail of the folio straddling i_size). A non-writeback caching fuse file system uses neither path, so it has to zero the tail itself from the size-extending paths, like XFS (xfs_file_write_zero_eof()) and ext4 (ext4_block_zero_eof()) do. Call truncate_pagecache_range() over the newly-exposed range up front from the three paths that extend a file, before the new size is published: - a buffered write whose position is past the old EOF (fuse_perform_write()); - a size-extending setattr/truncate (fuse_do_setattr()); - a size-extending fallocate (fuse_file_fallocate()). This unmaps the stale mappings and zeroes the partial tail of the old EOF folio, so a later read returns zeros. Truncating [old EOF, write start) before a buffered write keeps the dropped range disjoint from the written data, so a write that lands inside the old EOF folio is preserved. writeback_cache connections are unaffected, as their writes go through iomap_file_buffered_write(), which zeroes post-EOF folios. The bug is observable on a non-writeback_cache server that returns FOPEN_KEEP_CACHE on writable files (without FOPEN_DIRECT_IO), and is caught by the new write_extend_eof fuse selftest. Signed-off-by: Jimmy Zuber <jamz@amazon.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> |
||
|
|
1f59015e95 |
fuse: Fix the condition to enable over-io-uring
The existing condition in fuse_uring_cmd() is there only to avoid
disabling io-uring for connections that already run with it, missing
was a condition to refuse any IORING_OP_URING_CMD if the
connection/channel didn't get enabled because of missing FUSE_INIT
reply flag FUSE_OVER_IO_URING. Without the reply flag the barrier in
fuse_uring_ready() doesn't work and IO could already be going on and
cause deadlock states (at a minimum one between fch->bg_lock and
queue->lock).
The change itself is trivial, but brings behavior change,
FUSE_OVER_IO_URING has to be set in the FUSE_INIT_REPLY by fuse servers
to accept any IORING_OP_URING_CMD. Libfuse does that and the only
non-libfuse implementation I found (fractal-fuse) also does it.
Qemu patches for fuse-io-uring are not merged yet, as far as I know.
Moved up is the smp_load_acquire(&fch->initialized) check, as a
fuse-server implementation might try to setup io-uring before FUSE_INIT
is processed and might have gotten -EOPNOTSUPP instead of -EAGAIN.
Also fixed is a stale comment that explains the handling of the
FUSE_OVER_IO_URING flag in early RFC versions.
If there should be a report from any library or application we
probably need to revert this commit.
Fixes:
|
||
|
|
26d7e1f5c4 |
fuse: invalidate the correct range after O_APPEND direct write
fuse_direct_write_iter() captures pos before generic_write_checks(),
which moves ki_pos to EOF for O_APPEND writes:
fuse_direct_write_iter()
{
pos = iocb->ki_pos; /* 0 (user-supplied) */
generic_write_checks(); /* ki_pos -> EOF */
fuse_direct_io(); /* writes at EOF, correct */
invalidate(pos, pos + res); /* [0, res) -- wrong */
}
The post-write invalidation targets a stale range instead of the
actual written range at EOF.
This can cause data inconsistency when the file size is not
page-aligned. The tail page straddling EOF has a valid portion
before EOF that concurrent readers can fault back in during the
DIO write window:
Tail page (file size X not page-aligned):
page_start X (EOF) page_end
|--- valid data ----|-- stale --|
CPU0 (O_APPEND DIO writer) CPU1 (buffered reader)
-------------------------- ----------------------
invalidate [X, X+len)
tail page evicted
FUSE_WRITE in flight ...
read [page_start, X)
tail page re-faulted
[X, page_end) = stale
FUSE_WRITE completes
i_size = X + len
invalidate [0, len) <- WRONG
tail page still cached
read [X, X+len)
hits stale tail page
returns old data
Fix by reading pos back from iocb->ki_pos after generic_write_checks(),
as generic_file_direct_write() does.
Also fix a typo in the comment ("may have" -> "may have competed").
Fixes:
|
||
|
|
a7d28aa0e9 |
erofs: simplify z_erofs_gbuf_growsize()
- Use guard(mutex)() to manage gbuf_resize_mutex; - Nullify tmp_pages after successful allocation, so that the error path becomes clearer. Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Gao Xiang <xiang@kernel.org> |
||
|
|
a7d097cf01 |
erofs: skip sufficiently large global buffers when resizing
z_erofs_gbuf_nrpages is advanced only after every global buffer has been
grown. If a resize fails after some buffers were enlarged, a retry
revisits those enlarged buffers.
Retrying the same size then returns -ENOMEM because alloc_pages_bulk()
has no pages to add and the unchanged return value is treated as a
failure. Retrying an intermediate size allocates a temporary pointer
array smaller than gbuf->nrpages and copies more existing pointers than
the array can hold.
Skip buffers that already satisfy the request. Once all remaining
buffers have caught up, advancing z_erofs_gbuf_nrpages again describes
the guaranteed minimum size across the pool.
Fixes:
|
||
|
|
c77516e1e6 |
erofs: support large folios in inode_share mode
erofs_fill_inode() calls mapping_set_large_folios() on each erofs file's own mapping, but in inode_share mode reads are routed to the shared inode's page cache instead, whose mapping never had large folio support enabled. Set up large folios for the shared inode's mapping as well. Signed-off-by: Jingbo Xu <jefflexu@linux.alibaba.com> Reviewed-by: Gao Xiang <xiang@kernel.org> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Gao Xiang <xiang@kernel.org> |
||
|
|
e8325399d6 |
erofs: support splice() in inode_share mode
erofs_ishare_fops routes everything that touches the page cache to the backing file in ->private_data: read_iter clones the iocb onto it, mmap does vma_set_file(), fadvise calls vfs_fadvise() on it. splice_read was left as filemap_splice_read(), which works on the user file's own mapping: it does init_sync_kiocb(&iocb, in), and filemap_get_pages() then takes iocb->ki_filp->f_mapping. So splice() and sendfile() fill the per-inode page cache rather than the shared one. The content is the same either way, since erofs_fill_inode() sets a_ops on that mapping too, which is why this went unnoticed. Two identical 8 MiB files under inode_share, reading one of them with splice(2) alone, in pages: before own 2048 shared 0 after own 0 shared 2048 "own" is cachestat(fd), which reports the file's own mapping; "shared" is mmap()+mincore(), which erofs_ishare_mmap() redirects to the backing file. Read through the backing file, as read_iter already does. Link: https://lore.kernel.org/all/b7dc7192-d586-45a2-bc4a-b41dc681c9bb@linux.alibaba.com/ Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com> Reviewed-by: Jingbo Xu <jefflexu@linux.alibaba.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Gao Xiang <xiang@kernel.org> |
||
|
|
8ebf958978 |
erofs: support SEEK_HOLE/SEEK_DATA in inode_share mode
When inode_share is enabled, erofs_ishare_fops.llseek falls back to generic_file_llseek, which treats the whole file as data and always returns i_size for SEEK_HOLE, hiding real holes in sparse files. Switch it to erofs_file_llseek instead. For user files f_mapping->host is always the real erofs inode, so SEEK_HOLE/SEEK_DATA resolve the per-file on-disk layout via iomap_seek_hole()/iomap_seek_data(). Reviewed-by: Gao Xiang <xiang@kernel.org> Signed-off-by: Jingbo Xu <jefflexu@linux.alibaba.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Gao Xiang <xiang@kernel.org> |
||
|
|
ab74edaeb1 |
erofs: Fix EROFS_FS_ZIP_LZMA_DEFAULT_MAX_STREAMS default logic
When NR_CPUS is less than 16, or when SMP is disabled, the default value
of 16 is invalid.
While actual configuration picks up a sensible and valid default
(NR_CPUS or 1), "make savedefconfig" will still write a line like
CONFIG_EROFS_FS_ZIP_LZMA_DEFAULT_MAX_STREAMS=1
to the defconfig file, even if that matches the sensible default.
Avoid needlessly enlarging the defconfig files, and reduce churn for
updating them, by specifying valid defaults depending on SMP and
NR_CPUS.
While at it, make the prompt depend on SMP, as there is no point in
asking the user about the maximum number of decompression streams if
there is only one valid answer.
Fixes:
|
||
|
|
388b607d10 |
EFI updates for v7.3
- Set a timeout for EFI runtime service completions, and declare the firmware wedged if it is exceeded. Note that this requires special handling in case the firmware does return after all. - Rate limit the efivarfs statfs() handler as the QueryVariableInfo() runtime service can be costly - Sanity check the size of struct properties_header on Mac/x86 - Tweak the prototype of efi_guid_to_str() -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQQQm/3uucuRGn1Dmh0wbglWLn0tXAUCaoqdVQAKCRAwbglWLn0t XAb1AP9DIuHIAYlD4j8FKXcJtq1O/MzOadE3c4fNIdTPlTeUaAD8CAP0gHG3iRvc G265QOG2tjmmnFbCe+R8JVSdXBwCEAU= =GNJQ -----END PGP SIGNATURE----- Merge tag 'efi-next-for-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi Pull EFI updates from Ard Biesheuvel: - Set a timeout for EFI runtime service completions, and declare the firmware wedged if it is exceeded. Note that this requires special handling in case the firmware does return after all - Rate limit the efivarfs statfs() handler as the QueryVariableInfo() runtime service can be costly - Sanity check the size of struct properties_header on Mac/x86 - Tweak the prototype of efi_guid_to_str() * tag 'efi-next-for-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi: efivarfs: Rate limit statfs() handler efi: apple-properties: validate setup data header length efi: make efi_guid_to_str() take a const GUID pointer efi/runtime-wrappers: retire the worker if a wedged call ever returns efi/runtime-wrappers: honour EFI_RUNTIME_SERVICES in the non-blocking paths efi/runtime-wrappers: bound the wait for EFI runtime service calls efi/runtime-wrappers: check EFI_RUNTIME_SERVICES before using efi_rts_work efi/runtime-wrappers: handle queue_work() failure with goto exit efi/runtime-wrappers: factor out efi_rts_park_worker() efi: fix stale reference to efi_recover_from_page_fault() |
||
|
|
61a09cfc12 |
This contains a set of 142 SMB server updates focused on SMB2 command
sequencing, SMB3 request replay and encryption, Apple Time Machine
interoperability, protocol-compatibility fixes validated with smbtorture,
security hardening, SMB Direct transport support, connection reliability,
and other correctness improvements.
New features:
- Implement the SMB2 command sequence window.
Enforce the credit-based MessageId range for each connection, rejecting
out-of-window, duplicate, and wrapped sequence numbers. This prevents
invalid requests and same-channel replays from being processed.
- Add SMB3 request replay support.
SMB3 clients may resend requests with SMB2_FLAGS_REPLAY_OPERATION after
a channel disconnect when the original response was lost. Track the
required channel and open state to safely handle durable CREATE replays
and make oplock, lease, and lock replays idempotent, avoiding duplicate
state changes and improving multichannel reconnect reliability.
- Add opt-in Apple Time Machine support.
Implement the AAPL negotiation and related Finder, stream, COPYCHUNK,
sparse-file, CHANGE_NOTIFY, and RPC compatibility required for Time
Machine shares, allowing macOS backupd to use ksmbd for backups.
- Add per-share SMB3 encryption support.
Allow individual shares to require SMB3 encryption by advertising
SMB2_SHAREFLAG_ENCRYPT_DATA in TREE_CONNECT responses and rejecting
unencrypted tree connects and plaintext requests for protected shares.
- Add SMB Direct RDMA encryption support.
Extend SMB Direct to support SMB3 encrypted payloads over RDMA, with
transform negotiation and encryption/decryption for RDMA READ/WRITE.
Other changes:
- Parse and retain AppInstanceVersion contexts, enforce version ordering,
close older active handles for newer takeovers, and reject invalid or
unversioned opens according to the SMB2 semantics.
- Accept durable reconnect requests that omit VolatileFileId when the
persistent ID and reconnect context identify the handle, while
continuing to reject explicit volatile-ID mismatches.
- Fix SMB2/SMB3 protocol validation and security issues, including request
offsets, file and object IDs, IPC responses, output buffer sizes,
SMB3.1.1 binding validation, signing-required handling, durable handles,
ACLs, maximal access, and security information.
- Fix heap out-of-bounds accesses, use-after-free bugs, memory leaks,
invalid pointer dereferences, and sensitive-data lifetime issues in
authentication, Kerberos, preauthentication, sessions, connections,
and module teardown.
- Correct alternate-data-stream and named-stream handling, COPYCHUNK
behavior, sparse-file and compression attributes, allocated-range
queries, file trimming, duplicate extents, DOS attributes, snapshots,
normalized names, and partial information responses.
- Fix locking, lease, oplock, durable reconnect, async request, and
CHANGE_NOTIFY races, including deferred-lock rollback, parent directory
lease notifications, and connection teardown lifetime bugs.
- Fix SMB3 encryption handling for compressed requests, expired encrypted
sessions, interim responses, bound multichannel connections, and
decryption failures.
- Fix SMB3 multichannel session lookup and session state transitions so
changes are scoped to the correct bound connections and cannot revive
connections that are already shutting down.
- Fix DACL access checks so ACE walks are bounded by the declared DACL
size, preventing data beyond the DACL boundary from being interpreted
during access validation.
- Fix session accounting and lifetime issues, including session counter
updates during publication and removal, session leaks on registration
failure, and procfs creation diagnostics.
- Improve TCP connection reliability by enabling TCP keepalive for
accepted connections and preserving TCP timers for kernel sockets,
preventing silent peers from holding connections indefinitely.
- Fix smbdirect RDMA cleanup ordering for completion queues, QPs, child
sockets, and listener locking.
- Improve async response framing, multi-iovec signing, RPC pipe status
handling, and ksmbd procfs monitoring for server, share, connection,
session, and open-file state.
- Remove the obsolete DES crypto header and Kconfig dependency now that
NTLMv1 support has been removed.
- Update the ksmbd repository URL in MAINTAINERS and add an additional
KSMBD reviewer.
-----BEGIN PGP SIGNATURE-----
iQJKBAABCgA0FiEE6NzKS6Uv/XAAGHgyZwv7A1FEIQgFAmqKrvwWHGxpbmtpbmpl
b25Aa2VybmVsLm9yZwAKCRBnC/sDUUQhCExxEACUk9E89TrgHUlSni/U4WEcg95n
YNVm+oeRNnpqu7axGtIqmzgc7eU96ofR8un0pNLjkdWSD27hv6bmUv0e2+uOI7LU
04FIwJfOLPR4roKgwyLhC+I88zjHWBxU2fAx1l0ksFpTAF4vFuo2Il/TsaM57QEm
qhE0laiLV95jrtafnW8l2E+Be+qsRy7wRrj69IThfBBpwEMvehL3JK42yDItLKUm
ETKJuO4O3QCN1tyMlntzshdLhuFIWrnNspTwKqMEE9/Ba4cuzGrcm6Y4tLDHDX/j
Vr45w6rFsULJhw2mSz8cRYV3HcrPea7CVynJVDYtdIAngez0O3iLE5qAM1gff0HG
5H4N57ye3iabySD9B9Hy8ISqreCGW7dNZf3LACmZyeXjNGmxGB4nrgTc9fz1SAcl
JizpgMxrh2xj0YmABShgfqHFn9u+QvWaMIDYUddIQ+fX1Y+TxHDPssGJ0ygXCyJ0
BrIwqRHgL7XONY2sx8bPWExAzVZq/4gPWVZACM7X138iuR1kDIEpnPqvMMpPx8am
x5jSgvQ8NdABxLUZWU3BhcJseGG4gbvq0HzYibR6MPNy6P5ct3q+ifiWuY/JZ8Op
ZTxcyShSXziy8uk7iKvGgS3eJ5bDSb2Wo9flkvoCifG7VgPfDec3d/V4f1n9cTix
2TpmzQRF98f6arzzSQ==
=uocO
-----END PGP SIGNATURE-----
Merge tag 'ksmbd-for-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/smb
Pull smb server updates from Namjae Jeon:
"This contains server updates focused on SMB2 command sequencing, SMB3
request replay and encryption, Apple Time Machine interoperability,
protocol-compatibility fixes validated with smbtorture, security
hardening, SMB Direct transport support, connection reliability, and
other correctness improvements.
New features:
- Implement the SMB2 command sequence window
Enforce the credit-based MessageId range for each connection,
rejecting out-of-window, duplicate, and wrapped sequence numbers.
This prevents invalid requests and same-channel replays from being
processed
- Add SMB3 request replay support
SMB3 clients may resend requests with SMB2_FLAGS_REPLAY_OPERATION
after a channel disconnect when the original response was lost.
Track the required channel and open state to safely handle durable
CREATE replays and make oplock, lease, and lock replays idempotent,
avoiding duplicate state changes and improving multichannel
reconnect reliability
- Add opt-in Apple Time Machine support
Implement the AAPL negotiation and related Finder, stream,
COPYCHUNK, sparse-file, CHANGE_NOTIFY, and RPC compatibility
required for Time Machine shares, allowing macOS backupd to use
ksmbd for backups
- Add per-share SMB3 encryption support
Allow individual shares to require SMB3 encryption by advertising
SMB2_SHAREFLAG_ENCRYPT_DATA in TREE_CONNECT responses and rejecting
unencrypted tree connects and plaintext requests for protected
shares
- Add SMB Direct RDMA encryption support
Extend SMB Direct to support SMB3 encrypted payloads over RDMA,
with transform negotiation and encryption/decryption for RDMA
READ/WRITE
Other changes:
- Parse and retain AppInstanceVersion contexts, enforce version
ordering, close older active handles for newer takeovers, and
reject invalid or unversioned opens according to the SMB2 semantics
- Accept durable reconnect requests that omit VolatileFileId when the
persistent ID and reconnect context identify the handle, while
continuing to reject explicit volatile-ID mismatches
- Fix SMB2/SMB3 protocol validation and security issues, including
request offsets, file and object IDs, IPC responses, output buffer
sizes, SMB3.1.1 binding validation, signing-required handling,
durable handles, ACLs, maximal access, and security information
- Fix heap out-of-bounds accesses, use-after-free bugs, memory leaks,
invalid pointer dereferences, and sensitive-data lifetime issues in
authentication, Kerberos, preauthentication, sessions, connections,
and module teardown
- Correct alternate-data-stream and named-stream handling, COPYCHUNK
behavior, sparse-file and compression attributes, allocated-range
queries, file trimming, duplicate extents, DOS attributes,
snapshots, normalized names, and partial information responses
- Fix locking, lease, oplock, durable reconnect, async request, and
CHANGE_NOTIFY races, including deferred-lock rollback, parent
directory lease notifications, and connection teardown lifetime
bugs
- Fix SMB3 encryption handling for compressed requests, expired
encrypted sessions, interim responses, bound multichannel
connections, and decryption failures
- Fix SMB3 multichannel session lookup and session state transitions
so changes are scoped to the correct bound connections and cannot
revive connections that are already shutting down
- Fix DACL access checks so ACE walks are bounded by the declared
DACL size, preventing data beyond the DACL boundary from being
interpreted during access validation
- Fix session accounting and lifetime issues, including session
counter updates during publication and removal, session leaks on
registration failure, and procfs creation diagnostics
- Improve TCP connection reliability by enabling TCP keepalive for
accepted connections and preserving TCP timers for kernel sockets,
preventing silent peers from holding connections indefinitely
- Fix smbdirect RDMA cleanup ordering for completion queues, QPs,
child sockets, and listener locking
- Improve async response framing, multi-iovec signing, RPC pipe
status handling, and ksmbd procfs monitoring for server, share,
connection, session, and open-file state
- Remove the obsolete DES crypto header and Kconfig dependency now
that NTLMv1 support has been removed
- Update the ksmbd repository URL in MAINTAINERS and add an
additional KSMBD reviewer"
* tag 'ksmbd-for-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/smb: (142 commits)
MAINTAINERS: update ksmbd repository URL
MAINTAINERS: add myself as KSMBD reviewer
smb: server: remove unused DES crypto header
smb: server: Remove obsolete "select CRYPTO_LIB_DES" from Kconfig file
ksmbd: keep TCP timers alive for kernel sockets
ksmbd: enable TCP keepalive for accepted connections
smb/server: fix session counter on session removal
smb/server: update session counter under sessions table lock
smb/server: fix session leak in ksmbd_session_register()
smb/server: warn if ksmbd_proc_create() fails
ksmbd: bound smb_check_perm_dacl() ACE walks by DACL size
ksmbd: make RDMA encryption diagnostics conditional
ksmbd: add SMB Direct RDMA encryption transform
ksmbd: handle encrypted compressed requests
ksmbd: decrypt requests from expired encrypted sessions
ksmbd: disconnect on SMB3 decryption failure
ksmbd: encrypt interim responses to encrypted requests
ksmbd: scope session state changes to bound connections
ksmbd: fix encrypted request lookup on bound channels
ksmbd: add per-share SMB3 encryption enforcement
...
|
||
|
|
e5f9260615 |
mm.git review status for master..mm-nonmm-stable
Total patches: 95 Reviews/patch: 0.63 Reviewed rate: 56% Summary of patch series in this merge: - "ocfs2/dlm: bound peer-controlled lengths in the o2dlm" (Bryam Vargas): Validate and bound all input lengths and count fields in the o2dlm migration and recovery receive handlers to prevent memory corruption and kernel panics from malformed cluster messages - "ocfs2: validate xattr entry bounds" (Cen Zhang): Validate OCFS2 extended attribute entry name and value bounds during metadata reads to prevent out-of-range memory accesses during retrieval or listing operations. - "taskstats: fix cgroupstats invalid fd handling and add selftests" (Yiyang Chen): Return -EBADF when cgroupstats receives an invalid file descriptor to prevent caller hangs and misleading success ACKs. Add a kselftest to validate valid cgroup v1 queries and verify proper error handling across different Netlink flag combinations. - "misc lib/raid/ improvements v2" (Christoph Hellwig): Improve benchmark-based algorithm selection for the XOR and RAID6 libraries, add KUnit benchmark tests, and cleanup minor implementation details. - "ocfs2: cluster: o2hb_region_pin() fixes" (Joseph Qi): Fix sleeping-in-atomic, lock order inversion and error-path cleanup bugs in o2hb_region_pin() by releasing o2hb_live_lock across sleeping configfs_depend_item() calls and using unlocked variants from callback context. Ensure failed pin attempts properly decrement user counts and unpin partially initialized heartbeat regions to prevent memory leaks and unprotected states. - "lib/ucs2_string.c: fix out-of-bounds read in ucs2_strnlen()" (Vincent Mailhol) Fix an off-by-one which could cause an out-of-bounds read. - "ocfs2: harden heartbeat teardown races" (Cen Zhang): Fix two OCFS2 heartbeat/o2net teardown races found by KASAN. - "taskstats: tidy up the cpumask command path" *Bradley Morgan) make two small cleanups in kernel/taskstats.c. - "ocfs2: validate active orphan slots during inode read" (ZhengYuan Huang): Validate active ordinary and append-DIO orphan slots read from OCFS2 dinodes at the metadata boundary to prevent corrupted slot indices from causing out-of-bounds array accesses. - "ocfs2: bound-check both readdir re-validation scans" (Zhan Xusheng) Enforce strict boundary checks on directory entry record lengths and offset calculations during OCFS2 directory re-scans to prevent out-of-bounds memory reads and directory position corruption. -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQTTMBEPP41GrTpTJgfdBJ7gKXxAjgUCaoo38wAKCRDdBJ7gKXxA jnKuAP9tIUJoYIzxG7zr00qJj95gczgE0+GikN1wXfO9Cvh8QAEAqr5InWrANTBB l4qW3/o4hM9TlBdr84oT3RNnvBicuwA= =BY1d -----END PGP SIGNATURE----- Merge tag 'mm-nonmm-stable-2026-08-22-16-57' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Pull non-MM updates from Andrew Morton: - "ocfs2/dlm: bound peer-controlled lengths in the o2dlm" (Bryam Vargas) Validate and bound all input lengths and count fields in the o2dlm migration and recovery receive handlers to prevent memory corruption and kernel panics from malformed cluster messages - "ocfs2: validate xattr entry bounds" (Cen Zhang) Validate OCFS2 extended attribute entry name and value bounds during metadata reads to prevent out-of-range memory accesses during retrieval or listing operations. - "taskstats: fix cgroupstats invalid fd handling and add selftests" (Yiyang Chen) Return -EBADF when cgroupstats receives an invalid file descriptor to prevent caller hangs and misleading success ACKs. Add a kselftest to validate valid cgroup v1 queries and verify proper error handling across different Netlink flag combinations. - "misc lib/raid/ improvements v2" (Christoph Hellwig) Improve benchmark-based algorithm selection for the XOR and RAID6 libraries, add KUnit benchmark tests, and cleanup minor implementation details. - "ocfs2: cluster: o2hb_region_pin() fixes" (Joseph Qi) Fix sleeping-in-atomic, lock order inversion and error-path cleanup bugs in o2hb_region_pin() by releasing o2hb_live_lock across sleeping configfs_depend_item() calls and using unlocked variants from callback context. Ensure failed pin attempts properly decrement user counts and unpin partially initialized heartbeat regions to prevent memory leaks and unprotected states. - "lib/ucs2_string.c: fix out-of-bounds read in ucs2_strnlen()" (Vincent Mailhol) Fix an off-by-one which could cause an out-of-bounds read. - "ocfs2: harden heartbeat teardown races" (Cen Zhang) Fix two OCFS2 heartbeat/o2net teardown races found by KASAN. - "taskstats: tidy up the cpumask command path" *Bradley Morgan) make two small cleanups in kernel/taskstats.c. - "ocfs2: validate active orphan slots during inode read" (ZhengYuan Huang) Validate active ordinary and append-DIO orphan slots read from OCFS2 dinodes at the metadata boundary to prevent corrupted slot indices from causing out-of-bounds array accesses. - "ocfs2: bound-check both readdir re-validation scans" (Zhan Xusheng) Enforce strict boundary checks on directory entry record lengths and offset calculations during OCFS2 directory re-scans to prevent out-of-bounds memory reads and directory position corruption. * tag 'mm-nonmm-stable-2026-08-22-16-57' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (95 commits) mailmap: fix bouncing address for Taniya Das ocfs2: bound-check dir entries in the inline-data re-validation scan ocfs2: bound-check dir entries in the readdir re-validation scan squashfs: avoid thundering-herd cache wakeups prctl: fix PR_SET_MM_AUXV losing the forced AT_NULL terminator mailmap: update email address for Linfeng Sun lib/interval_tree: fix allocation warning messages checkpatch: add NOKPROBE_SYMBOL to the whitelist of lines that can occur immediately after functions Squashfs: check block offset is not negative signal: factor out the kernel reserved si_code check ocfs2: fix readdir position truncation on 32-bit kernels ocfs2: fix cached cluster count after suballocator reclaim ocfs2: fix circular locking dependency in ocfs2_init_acl() ocfs2: validate DIO orphan slot during inode read ocfs2: validate orphan slot during inode read selftests/prctl: fix non-anonymous VMA mapping in set-anon-vma-name test MAINTAINERS: add IRC and patchwork for LTP include/linux/list.h: mark list_add and __list_add as __always_inline tools/mm: prevent page_owner_sort from truncating input hung_task: update DETECT_HUNG_TASK_BLOCKER Kconfig help ... |
||
|
|
0d78592583 |
Miscellaneous futex fixes:
- Series to enforce that private futex owner shares the mm when
attaching. (Kyle Zeng, Thomas Gleixner)
- Fix race on the initial mm->futex.phash.ref allocation
(Hyunwoo Kim)
- Fix might_sleep() warning in futex_pivot_pending()
(Peter Zijlstra)
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-----BEGIN PGP SIGNATURE-----
iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAmqKGJwRHG1pbmdvQGtl
cm5lbC5vcmcACgkQEnMQ0APhK1iKxhAAj+A3L8a1OHRCKCMIE1gbk+bL5CYYrDqf
TO642/rGmvvrMdNtocK3IbzIady0umhZFrPqIRJcN5SAnoZf6mL5uD4XaR4xgaTp
prbNTXJrxzPMN5u3DcqnlWfGwFYXZxJIN6WBZCT7N6D/czr0Mqh7+Isdxey6nDWp
zWZfJ4DeVbSbf+2zft6pjwzXQAljyvEYEilV8+xgzwNfJjmG1QRS+MisPjjuGMZh
4C5bTTo966WgyKCu0MdtuP9a/WFT4ZUMWXXCB89Dz3mXImntltu+0rYEsg00I/NA
lSjEOnTpozqQwLPAUGBwGQRCP8tbPxRW9k+dmWUKY7/Ox5QtoNRzMt1n2hcG2uXk
VkefzABd0HWvUOYy8LL1o32rxdv78iqmfVxKyORHZKBS59OM+CAahCvgV9bVgE+g
Rbp1RzsPZJOEBkDY6bncyUN0Qm7bQqoCXt4ZEaX/Cj7lPRrCjzj+NXzuYKUReib1
z79Xnrps4r5QlY1PVICF4lKAWnUsLRSr/A+vPYgTJRQKTo0DwDaPTcEs4DrcAZ1j
0uTlk2B/mcThEDEd+kB7vBZcc7QnNsh8Qp5objXNPsq/7+8cJdHwXY1/qxsXgLFf
aQMhKJY/kfoE24yyb18SosXqMoxc8rDZkMKv91z597PlqIWbPMhNeg/dGlx8ptcl
S4DIaIZgJ5E=
=9ORp
-----END PGP SIGNATURE-----
Merge tag 'locking-urgent-2026-08-22' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull futex fixes from Ingo Molnar:
- Enforce that the private futex owner shares the mm when attaching
(Kyle Zeng, Thomas Gleixner)
- Fix race on the initial mm->futex.phash.ref allocation (Hyunwoo Kim)
- Fix might_sleep() warning in futex_pivot_pending() (Peter Zijlstra)
* tag 'locking-urgent-2026-08-22' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
futex: Fix might_sleep() warning in futex_pivot_pending()
futex: Fix race on the initial mm->futex.phash.ref allocation
futex: Clean up the redundant exit/exec functions
futex/pi: Plug private futex exec() race
futex: Sanitize and document task_struct::futex::state transitions
futex/pi: Reject cross-mm private futex owners
|
||
|
|
e13629f4df |
This update includes two minor fixes that have been siting on linux-next
for the past weeks.
- A patch from David removing the normalization function that we no
longer use.
- A patch from me fixing a parsing issue in the encoding version
argument passed by filesystems.
-----BEGIN PGP SIGNATURE-----
iJEEABYKADkWIQS3XO7QfvpFoONBhH1OwQgI3t8RJgUCanye+hsUgAAAAAAEAA5t
YW51MiwyLjUrMS4xMiwyLDIACgkQTsEICN7fESZ59wD/aQfEw7bAa7O6y1MDzOOj
Y27G2VhWTAvD0+gzi3mryMoBAIIw2/V1ASqovMxbxfx8ClwQtz2nwwW8LKFmntIJ
nkoI
=a9pQ
-----END PGP SIGNATURE-----
Merge tag 'unicode-for-next-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/krisman/unicode
Pull unicode updates from Gabriel Krisman Bertazi:
"Two minor fixes:
- Remove the normalization function that we no longer use (David Alan
Gilbert))
- Fix a parsing issue in the encoding version argument passed by
filesystems (me)"
* tag 'unicode-for-next-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/krisman/unicode:
unicode: Properly reject invalid encoding version strings
utf8: Remove unused utf8_normalize
|
||
|
|
728785f8fb |
This contains a set of nine exfat fixes covering shared writable mappings,
entry error handling, allocation cleanup, FITRIM bounds, and locking:
- Fix valid_size extension over shared writable mappings by lazily
zeroing page-cache gaps and ensuring racing stores cannot be
overwritten or extend beyond valid_size.
- Clean up partially written directory entries on add-entry failure and
safely free new directory clusters.
- Free a newly allocated directory cluster when zeroing it fails.
- Write the destination entry before removing the source entry during
rename, preserving the source if the destination write fails.
- Keep FITRIM within the requested range, even when the free-space search
wraps around the allocation bitmap.
- Fix truncated FS_IOC_GETFSLABEL results by passing the destination
buffer size in bytes to the UTF-16-to-NLS conversion.
- Fix overflow in the cluster-to-dentry calculation, which could cause
readdir to stop early on large volumes.
- Replace the per-inode truncate_lock with inode_lock, using shared
locking in bmap to serialize against concurrent truncation.
- Update the exfat mailing list address in MAINTAINERS.
-----BEGIN PGP SIGNATURE-----
iQJKBAABCgA0FiEE6NzKS6Uv/XAAGHgyZwv7A1FEIQgFAmqJqrAWHGxpbmtpbmpl
b25Aa2VybmVsLm9yZwAKCRBnC/sDUUQhCLIXEACnqHgNmrvIM6QtesU6iSVd6eGT
+7q+6ahkVv6dFks9KMc2hbzIs9VWmDpD3omU2OuqbJYiL3vuhv4+CwOnie6/5umc
3JCAG5jVOq5ee+7Tz6xZoxz2JxoxXm6LLmHXU0WALN4k8IsE7veGXAGkMgfnAQ44
lFDTByhvyf7vmXGHsz2FewOjdT6pdl4SUVAZQkvcZB9ujCqCWzx53s1+XZ2RCsT3
trepvTXQkxk2UyAKGs30JUiHDYwv01sYJCV84YKFBzTBCQ9AIIxKLCWlhYfERmLi
iL2nTBoNQPdDKiQK/R+axjkUABIQD3L4EhhqdLqcDBOFGsRlxUfd8pjyp+O5/yRw
Ev3ydGBDOULyU6Fmtx7mpzWm3EHklssMoGGuI9b81WcQc0PLp613egglgr1gKNZs
PaB74ea3ehSfHUIn2hF6Uli+OfZhXuHiOE/YKp6QTuer3rwUl0nJgIPDpkfWDuBH
hBGnTyiafMS0TVnd2yS0z8R/JipVpUniAPKLL5kRO3uIWcUwrRGjU8vfjsY5BSvU
W8BrYBu69zRQ603m/ARJ2gFU3jPmD7a/Su/m2GKaPjB/90RDbjRjcJ+r78pDfa1b
FgmL0cgyZg6uYFB0K/PCbSDsXA+x7xpjmOwZGgZNzrsFDQ+C9p5fizuOVG6N9MOg
zxOmKrpSSLYx0ahHgQ==
=kunx
-----END PGP SIGNATURE-----
Merge tag 'exfat-for-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat
Pull exfat updates from Namjae Jeon:
"A set of exfat fixes covering shared writable mappings, entry error
handling, allocation cleanup, FITRIM bounds, and locking:
- Fix valid_size extension over shared writable mappings by lazily
zeroing page-cache gaps and ensuring racing stores cannot be
overwritten or extend beyond valid_size
- Clean up partially written directory entries on add-entry failure
and safely free new directory clusters
- Free a newly allocated directory cluster when zeroing it fails
- Write the destination entry before removing the source entry during
rename, preserving the source if the destination write fails
- Keep FITRIM within the requested range, even when the free-space
search wraps around the allocation bitmap
- Fix truncated FS_IOC_GETFSLABEL results by passing the destination
buffer size in bytes to the UTF-16-to-NLS conversion
- Fix overflow in the cluster-to-dentry calculation, which could
cause readdir to stop early on large volumes
- Replace the per-inode truncate_lock with inode_lock, using shared
locking in bmap to serialize against concurrent truncation
- Update the exfat mailing list address in MAINTAINERS"
* tag 'exfat-for-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat:
exfat: replace truncate_lock with inode_lock
exfat: keep FITRIM within the requested range
exfat: fix truncated volume labels returned by FS_IOC_GETFSLABEL
exfat: fix overflow in cluster-to-dentry conversion
exfat: clean up new entry on add entry failure
exfat: free new directory cluster if zeroing fails
exfat: write moved entry before removing source
MAINTAINERS: update mailing list address for exfat
exfat: fix valid_size extension over a shared writable mapping
|
||
|
|
dafb84f092 |
f2fs: fix to propagate error from f2fs_sync_fs()
So that caller can detect any failure from f2fs_sync_fs(). Signed-off-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> |
||
|
|
a2c73a7a67 |
f2fs: return symlink writeback errors
F2FS writes long symlink data with page_symlink() and then flushes the
symlink mapping to reduce the chance of exposing a broken symlink.
That flush result is currently ignored. If the writeback fails, symlink()
still returns success even though the symlink is not durable and the same
operation can already surface -EIO through syncfs().
Return the writeback error to userspace and skip the dirsync flush once the
symlink data flush has failed.
Fixes:
|
||
|
|
11d56d7a8e |
f2fs: fix error handling on device alias check in rename and unlink
In f2fs_rename() and f2fs_unlink(), directly returning -EPERM when encountering a device aliasing file bypasses the cleanup path. Fix this by setting err to -EPERM and jumping to the proper cleanup labels (out_dir and out) instead of returning immediately. Reported-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr> Signed-off-by: Daeho Jeong <daehojeong@google.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> |
||
|
|
2b8704b6a8 |
f2fs: fix to reset all pinned status during fggc
Otherwise, the pinned status may affect latter flow of fggc.
Cc: stable@kernel.org
Fixes:
|
||
|
|
46d4246d8d |
f2fs: use f2fs_{down, up}_(read, write}_trace() for nat_tree_lock
Under heavy workloads or during background GC/fallocate operations,
nat_tree_lock can experience high lock contention between background
readers (e.g. f2fs_get_node_info() in gc_data_segment) and writers
(e.g. flush_nat_entries, set_node_addr, shrinker).
[375067.327986][T13777] schedule+0x4c/0x114
[375067.327997][T13777] f2fs_get_node_info+0x438/0x5c4
[375067.328002][T13777] f2fs_get_inode_page+0x1e0/0x3f0
[375067.328013][T13777] f2fs_iget+0x88/0x1180
[375067.328024][T13777] f2fs_lookup+0x168/0x3a8
[375067.328035][T13777] path_openat+0xa28/0x1b04
[375067.328046][T13777] do_filp_open+0xac/0x130
[375067.328056][T13777] do_sys_openat2+0x140/0x21c
[375067.328066][T13777] __arm64_sys_openat+0x70/0x9c
[375067.330299][T13777] schedule+0x4c/0x114
[375067.330310][T13777] schedule_preempt_disabled+0x24/0x40
[375067.330321][T13777] rwsem_down_write_slowpath+0x3b4/0x9d0
[375067.330332][T13777] down_write+0x98/0x170
[375067.330343][T13777] set_node_addr+0x74/0x4b4
[375067.330354][T13777] f2fs_new_node_page+0xb0/0x280
[375067.330444][T13777] f2fs_new_inode_page+0x3c/0x64
[375067.330455][T13777] f2fs_init_inode_metadata+0x4c/0x47c
[375067.330461][T13777] f2fs_add_regular_entry+0x258/0x5b8
[375067.330471][T13777] f2fs_add_dentry+0x100/0x158
[375067.330476][T13777] f2fs_do_add_link+0x84/0x140
[375067.330487][T13777] f2fs_create+0xec/0x250
[375067.331759][T13777] schedule+0x4c/0x114
[375067.331770][T13777] f2fs_down_read+0x9c/0xc4
[375067.331781][T13777] f2fs_need_inode_block_update+0x20/0x10c
[375067.331792][T13777] f2fs_do_sync_file+0x478/0x830
[375067.331802][T13777] f2fs_sync_file+0x2c/0x40
This patch converts nat_tree_lock to use the f2fs_{down,up}_{read,write}_trace
infrastructure.
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
|
||
|
|
af33c5a2a9 |
eCryptfs updates for 7.3-rc1
The set of eCryptfs changes for the 7.3-rc1 merge window consists of: - Hardening and fixes for maliciously crafted eCryptfs metadata in the lower encrypted file - Hardening and fixes for maliciously crafted userspace <-> kernel miscdev communications - Locking fixes for userspace <-> kernel miscdev communications - Fix to display encrypted filename related mount options - Clean up address_space_operations and reduce build dependencies by moving to filemap_dirty_folio() - Get rid of an unnecessary memory allocation in the inode update path - Kernel-doc formatting corrections The patches have all spent time in linux-next and they pass all tests in the ecryptfs-utils tree. I did manual validation of the miscdev fixes since we don't have test coverage for that feature. -----BEGIN PGP SIGNATURE----- iQJFBAABCgAvFiEEKvuQkp28KvPJn/fVfL7QslYSS/0FAmqHmJURHGNvZGVAdHlo aWNrcy5jb20ACgkQfL7QslYSS/3N9Q/+JFdmV0MU5oxbYMorJIfdR6cpRK28OvXN qaLX4wnQO3hvzILQ+GqX9KuFuqrIos3bbJpS5kGFjt2YpmVwFZwdcSQSLrHzxILA 6vexECAUmfJyVJqaraGzReZJYJfn3NBHrO8qizNzeuOGWqmvhSNIV5wi7T2yVaav LspVIjUtxaqHG4Sm2ZkW4Mm9T4wSYWl3QasyyV2Nir+KCdFekQS8GNx7LnkXm2L3 iqiEvijfNyVR4IVNnrzwdozIOqBqP5At4y1Uj+w4N7mjXzVEg158QV7nC1ndttGx z4HuomgQI0Xo61WYmQgb0omC7FIlFD422+nrrK3ZKFz881e1ozKd7hGa3r1gSeP9 lZma2GsQNYojYEWc/TgkyP/U3eUKVYeqmsWIyQjSKe1a1pmITgz8fMUiyegdVOSC Y20AH3fY0f8xRcUGv6BXeUYw4E5bED5Bh8/CgzcUpi5Vc3K3E/yxofrbZAuGJFSl KJ8Mfq9nsdVvuCWga2izglVecMWCjVuqM29yALh3nhmQXwuw6iJCF3Ob27kln97J GLmewNUj1tkhixzoGkx16VxEzrRR+GQoSnpmxXFvAke7EfHYkEQxlKF84phSsYR4 0hhP7EzhkgrNVXB2HB88LPTIBhO4fqoqCKPca33ZC4vMcDGuC4kJvXz/BiaY9CPp Y58PFrWNGjc= =LCDJ -----END PGP SIGNATURE----- Merge tag 'ecryptfs-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs Pull eCryptfs updates from Tyler Hicks: - Hardening and fixes for maliciously crafted eCryptfs metadata in the lower encrypted file - Hardening and fixes for maliciously crafted userspace <-> kernel miscdev communications - Locking fixes for userspace <-> kernel miscdev communications - Fix to display encrypted filename related mount options - Clean up address_space_operations and reduce build dependencies by moving to filemap_dirty_folio() - Get rid of an unnecessary memory allocation in the inode update path - Kernel-doc formatting corrections * tag 'ecryptfs-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs: ecryptfs: ecryptfs_kernel.h: clean up kernel-doc comments ecryptfs: use filemap_dirty_folio for address space operations ecryptfs: avoid heap allocation for inode size write ecryptfs: show filename encryption options eCryptfs: bound the packet-length peek to the user buffer ecryptfs: reject too-small tag 70 packets ecryptfs: fix tag 11 packet exact-fit size check ecryptfs: pass packet set buffer size to parser ecryptfs: hold msg ctx list lock when cleaning daemon queue ecryptfs: release message context on send failure ecryptfs: reject oversized encrypted_key_size in parse_tag_3_packet |
||
|
|
21bd0802cd |
RDMA v7.3 merge window pull
Quite alot of buf fixes again:
- Assorted locking, bounds-checking, cleanup, and error-path fixes across
UCMA/CMA, bng_re, bnxt_re, cxgb4, EFA, ERDMA, HFI1, HNS, ionic, iRDMA,
mlx4/mlx5, RXE, SIW, SRP/SRPT, and iSER target.
- netlink report for max # of supported resources
- get_zeroed_page()/etc removal
- Robust udata for ionic
- Allow unique RDMA device names per network namespace
- Completion counters and v2 admit queue support for EFA
- UC QP support for MANA
- Completion timestamps for ionic
- Harden uverbs data validation and resource lifetime handling, fixing several core use-after-free conditions.
- bnxt_re toggle-page ownership and lifetime bug fixes
- dmabuf SRQ support for mlx5
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQRRRCHOFoQz/8F5bUaFwuHvBreFYQUCaoeO2wAKCRCFwuHvBreF
YcyJAQCn8JeqTuayLchCARJX+9fazTaJES9zj41i3M8a7BfxCAEA2b266g0S660m
7eQ761NiIb1iklSl9rmt8vM22EMcngM=
=qcwp
-----END PGP SIGNATURE-----
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull RDMA updates from Jason Gunthorpe:
"About the normal size, still a lot of AI bug fixes and so on, but some
interesting new functionality too:
- Assorted locking, bounds-checking, cleanup, and error-path fixes
across UCMA/CMA, bng_re, bnxt_re, cxgb4, EFA, ERDMA, HFI1, HNS,
ionic, iRDMA, mlx4/mlx5, RXE, SIW, SRP/SRPT, and iSER target.
- netlink report for max # of supported resources
- get_zeroed_page()/etc removal
- Robust udata for ionic
- Allow unique RDMA device names per network namespace
- Completion counters and v2 admit queue support for EFA
- UC QP support for MANA
- Completion timestamps for ionic
- Harden uverbs data validation and resource lifetime handling,
fixing several core use-after-free conditions.
- bnxt_re toggle-page ownership and lifetime bug fixes
- dmabuf SRQ support for mlx5"
* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (160 commits)
RDMA/ucma: Allow path records to exactly fit the output buffer
RDMA/uverbs: Guard legacy bundles without method_elm
RDMA/efa: Add support for 128B admin v2 SQ entry
RDMA/efa: Generalize the admin SQ
RDMA/efa: Decouple admin command payload from admin header
RDMA/rxe: Fix OOB in free_rd_atomic_resources()
RDMA/cma: Fix WARNING in res_to_rt
RDMA/cxgb4: Free debugfs on registration failure
RDMA/cxgb4: Cancel reg_work before freeing device on remove
RDMA/ucma: Lock the handler in ucma_set_ib_path()
RDMA/ucma: Lock the handler in ucma_write_cm_event()
RDMA/erdma: restrict the driver to little-endian systems
RDMA/ionic: Embed counter driver data in rdma_counter allocation
RDMA/ionic: Cap eq_count to the eth driver's interrupt vector budget
RDMA/siw: Fix use-after-free in siw_accept()
IB/isert: post the full-feature receive buffers after session registration
IB/isert: delay the final Login Response until the session is registered
RDMA/srp: fix heap information leak on a truncated SRP_CRED_REQ
RDMA/erdma: Hold QP references for AE and CM processing
RDMA/erdma: Hold CQ references when processing EQ events
...
|
||
|
|
0ecd56573c
|
ext4: Avoid entering writeback paths during fastcommit replay
Fastcommit replay effectively happens in nojournal mode. This results in
ext4_mark_iloc_dirty() setting I_METADATA_WRITEBACK flag and as a result
we end up entering filesystem writeback functions. However during
fastcommit replay s_writepages_rwsem isn't initialized yet and hence we
crash.
Fix the problem by avoiding setting I_METADATA_WRITEBACK during
fastcommit replay. Journal replay flushes the whole block device after
replay anyway so all metadata is properly persisted and replay is faster
this way as a bonus.
Fixes:
|
||
|
|
a7b842f182 |
ntfs: support resident WOF decompression
Extend WOF decompression to support files where the reparse named data attribute or the compressed chunks themselves are resident. Retrieve resident metadata using ntfs_attr_lookup() and copy compressed chunks directly from the resident attribute payload. Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
2bef615ebf |
ntfs: add non-resident WOF decompression
Introduce non-resident Windows System Compression (WOF) decompression support. Add wof.c containing parse_wof_chunk_table() and ntfs_read_wof_compressed_block(), and routing them via transparent codec ops table with dynamic scratch memory allocation. Hook up ntfs_readpage/read_folio paths in aops.c to delegate to the WOF block reader when NInoWofCompressed is set. Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
7ddb3fef35 |
ntfs: implement codec ops for LZX and XPRESS
Implement the transparent compression codec ops for XPRESS (4K, 8K, 16K) and LZX (32K) algorithms. The xpress_scratch_size, lzx_scratch_size, xpress_decompress_chunk, and lzx_decompress_chunk wrappers provide unified interfaces and use per-call dynamic scratch state allocation (avoiding global mutexed singletons). Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
f39cd3f7fc |
ntfs: port lzx/xpress decompressors from ntfs-3g-system-compression
Port the LZX and XPRESS decompressors from the userspace ntfs-3g-system-compression plugin (Eric Biggers, https://github.com/ebiggers/ntfs-3g-system-compression) into the in-tree NTFS driver under lib/, and adapt them to the kernel environment. The upstream plugin implements WOF ("Windows Overlay Filesystem", a.k.a. system compression / "Compact OS") decompression for the NTFS-3G FUSE driver, and itself borrows the LZX/XPRESS decompressors that the same author wrote for wimlib (https://wimlib.net/). The XPRESS and LZX formats used here are identical to those used in WIM archives. This commit is the kernel-side port that lets fs/ntfs/wof.c read system-compressed files. The library keeps the upstream subtable-based Huffman decoder (root table + contiguous subtables decoded with MAKE_DECODE_TABLE_ENTRY()), so long codewords only need one extra lookup instead of bit-by-bit tree traversal. The ntfs_codec_ops interface exported to fs/ntfs/wof.c (ntfs_lzx32k_codec_ops and ntfs_xpress{4k,8k,16k}_codec_ops) matches what the WOF layer expects. Modifications made while porting from the upstream plugin: - Replace the variable LZX window order (2^15..2^21) with a fixed 32768-byte window, which is the only size WOF uses - Simplify the bitstream helper: - bitstream_ensure_bits() now guarantees 16 valid bits instead of the carried-over 17-bit refill path from wimlib. Neither LZX (max codeword length 16) nor XPRESS (max 15) needs more than 16 bits. - Refactor codes to satisfy checkpatch. Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
d7aa04984f |
ntfs: return errors from inode initialization
ntfs_iget() previously converted only -ENOMEM from ntfs_read_locked_inode() into an ERR_PTR(). Other initialization errors left the inode on the normal return path after it had been unlocked. Return every non-zero initialization error after releasing the inode reference. Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
760c9d271d |
ntfs: parse REPARSE_TAG_WOF
Introduce parsing support for REPARSE_TAG_WOF reparse points. Rename ntfs_make_symlink() to ntfs_parse_reparse() since it now handles both symlinks and WOF reparse tags. Introduce NI_WofCompressed flag to indicate files compressed via Windows System Compression (WOF), and configure compressed block size accordingly (12 to 15 bits based on the format). Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
56cc42a7b3 |
ntfs: return errors from ntfs_attr_readall
ntfs_attr_readall() currently loses the failure reason for attribute lookup, allocation, and read failures by returning NULL. Return ERR_PTR() with the original error instead. The reparse parser can then propagate allocation and I/O errors without treating them as filesystem corruption. Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
d38ce59d16 |
ntfs: add WOF compression config option
Add CONFIG_NTFS_FS_WOF_COMPRESSION for Windows system compression. Build XPRESS and LZX decoding code only when requested. Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
c34e33a60f |
ntfs: define LZNT1 codec ops under transparent codec interface
Define the ntfs_lznt1_codec_ops structure containing decompress_pages and compress_subblock callbacks in compress.c, and export it in ntfs_codec.h. This structure binds existing LZNT1 decompress and compress helper functions under the unified transparent compression interface. Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
f2240a2ff4 |
ntfs: introduce transparent compression codec interface
Introduce struct ntfs_codec_ops and enum ntfs_codec_id to provide a unified interface for compression and decompression algorithms. This interface supports WOF and LZNT1 decompression. Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
be9c45bdb1 |
xfs: replace ns_capable_noaudit
Now that capable_noaudit() is available, we don't need to keep using ns_capable_noaudit() and specifying the usernamespace every single time. Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org> |
||
|
|
4642259374 |
quota: Don't issue audit messages on quota enforcing
Calling capable() to determine if we can bypass quota enforcement or not can trigger spurious audit messages. We don't really require it here so just use the capable_noaudit() version. Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Acked-by: Jan Kara <jack@suse.cz> Signed-off-by: Carlos Maiolino <cem@kernel.org> |
||
|
|
e2f62a9744 |
xfs: fix capability check in xfs
An user reported a bug where he managed to evade group's quota by changing a file's gid to a different group id the same user belonged to, even though quotas were enforced on both gids and the file's size was big enough to exceed the quota's hardlimit. Commit |
||
|
|
885435535b |
xfs: restore bi_bdev in xfs_zone_gc_write_chunk
xfs_zone_gc_write_chunk relies on bi_bdev to still be valid, which is not
true when XFS is used on top of a stacked block device. This can lead to
misdirected GC writes, writing of plain text when using dm-crypt, or
miscalculated I/O limits in xfs_zone_gc_split_write.
Fix this by reassigning bi_bdev.
Fixes:
|
||
|
|
6b855256eb |
xfs: split ioend handling into a separate source file
The ioend handling used to be only for buffered writeback, but has been extended to direct I/O and reads. Split it into a new source file. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Hans Holmberg <hans.holmberg@wdc.com> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org> |
||
|
|
0510346e8e |
xfs: factor out a xfs_iomap_set_anon_write helper
De-duplicate the iomap setup for zoned writes. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Hans Holmberg <hans.holmberg@wdc.com> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org> |
||
|
|
4bc67fc800 |
xfs: fix zoned write iomap flags assignments
Don't overwrite IOMAP_F_DIRTY with IOMAP_F_ANON_WRITE, but ensure both flags are set instead. Note that in practice this is harmless as all zoned writes force a metadata transaction anyway, but incorrectly assigned flags are still a landmine that will cause problems at some point. Fixes: |
||
|
|
2d829cc767 |
xfs: fix racy open zone caching
When testing on very fast storage devices, I've observed writers using io_uring creating many open zones with just a few kiB written to it, which then don't get used. I tracked this down to multiple io_uring helper threads finding a full zone in i_private, and then going on to select a one, with the final one winning the race and leaving it in i_private. Fix this by dropping full zones from i_private as soon we find them, checking cached for a cached zoned when a single writes needs a new zone, and by keeping an existing cached zone in xfs_set_cached_zone when it still has space available, dropping the newly found/allocated one instead. This uses i_flags_lock as a low-level spinlock for short hold times to avoid interactions with the ilock, which is used for completions. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Hans Holmberg <hans.holmberg@wdc.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org> |
||
|
|
ae28561189 |
xfs: handle NULL open_zone for merged ioends in xfs_ioend_put_open_zones
In theory we could fail multiple ioends before an open zone was assigned
to them, and the iomap code could merge them. Check for NULL not only
for the main ioend but also all merged ones on ->io_list to handle this
case.
Fixes:
|
||
|
|
4e07cd78e1 |
xfs: use inode_init_always_gfp with __GFP_NOFAIL in xfs_inode_alloc
Just like the inode allocation itself, allocation of the security data
inside of inode_init_always(_gfp) must not fail here as we can be inside
an already dirty transaction context. Note that we do not have to pass
GFP_NOFS explicitly as we are already in a nofs context when in a
transaction, as seen by the call to alloc_inode_sb.
Also update the comment about this a bit to be more clear.
Fixes:
|
||
|
|
750a361bfc |
xfs: remove kmem_to_page()
kmem_to_page() has been unused since commit
|
||
|
|
7fc296b379 |
xfs: don't flush and invalidate internal RT device twice in xfs_shutdown_devices
Check for an internal RT device to remove a bit of extra work.
Fixes:
|
||
|
|
b9b541e70d |
xfs: split an assert in xfs_trans_log_buf
Split the "irst <= last && last < BBTOB(bp->b_length)" assert into two to make it clear which condition fired. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Signed-off-by: Carlos Maiolino <cem@kernel.org> |
||
|
|
41a28c865d |
xfs: don't hold buffer locks across sync transaction commit in xfs_sync_sb_buf
xfs_sync_sb_buf() holds sb/rtsb buffer locks across a synchronous
xfs_trans_commit(), which flushes the CIL push workqueue internally.
If shutdown occurs during the CIL push, xfs_buf_item_unpin() needs to
lock these buffers to fail them, causing a deadlock:
setlabel: holds buf lock -> flush_workqueue(xfs-cil)
CIL push worker: xfs_buf_item_unpin -> xfs_buf_lock(same buf)
Remove the xfs_trans_bhold() calls so that commit releases the buffer
locks normally. After the sync commit, re-acquire the buffers via
mp->m_sb_bp / mp->m_rtsb_bp for the on-disk writeback.
Fixes:
|
||
|
|
ed3b875bea |
mm.git review status for mm-hotfixes-stable..mm-stable
Everything:
Total patches: 501
Reviews/patch: 1.66
Reviewed rate: 70%
Excluding DAMON:
Total patches: 356
Reviews/patch: 2.26
Reviewed rate: 90%
Excluding DAMON and selftests:
Total patches: 329
Reviews/patch: 2.31
Reviewed rate: 92%
Excluding DAMON, selftests and maple_tree:
Total patches: 328
Reviews/patch: 2.31
Reviewed rate: 92%
Summary of patch series in this merge:
- The 2 patch series "mm: drop "sub" prefix from various places" from
Dev Jain implements some page->folio conversion and a naming cleanup.
- The 2 patch series "mm/kasan: remove redundant initialization for
kasan_flag_write_only" from Igor Putko provides some KASAN cleanup work.
- The 2 patch series "mm/filemap: reduce unnecessary xarray lookups"
from Chi Zhiling provides a small speedup in the pagecaache read code.
- The 4 patch series "mm/percpu: Fix possible NOFS/NOIO reclaim
recursion" from Kaitao Cheng improves a few things in the vmalloc code -
mainly the avoidance of GFP_KERNEL allocations when the caller asked for
GFP_NOFS or GFP_NOIO.
- The 3 patch series "mm/kmemleak: avoid soft lockup when scanning task
stacks" from Breno Leitao avoids a soft lockup watchdog trigger from the
kmemleak scanning code in extreme situations.
- The 6 patch series "mm/page_owner: misc cleanups" from Ye Liu is a
collection of unrelated cleanups to the page_owner code. For some
reason lots of people have been working on the page_owner code this
cycle.
- The 4 patch series "mm: convert to walk_page_range_vma() to eliminate
find_vma()" from Kefeng Wang simplifies and accelerates the page walking
library function.
- The 3 patch series "mm/migrate: preparatory cleanups for batch copy
and offload" from Shivank Garg implements cleanups in the migration
code.
- The 4 patch series "mm/page_owner: add per-fd filter infrastructure
for print_mode and NUMA filtering" from Zhen Ni provides per-fd
filtering to page_owner in order to reduce the sometimes vast amount of
output it can produce.
- The 19 patch series "mm: Refactor bootmem gigantic hugepage
allocation" from Muchun Song is a "set of fixes and preparatory cleanups
around bootmem HugeTLB handling, sparse initialization ordering, and
related vmemmap setup".
- The 4 patch series "mm/zsmalloc: reduce lock contention in zs_free()"
from Wenchao Hao reduces lock contention in zs_free(), which dominates
the unmap path under memory pressure on Android (LMK kills) and on x86
servers running zswap-heavy workloads. Up to 1.83x improvement in
microbenchmarking.
- The 2 patch series "move alloc_tag.c file under mm/" from Suren
Baghdasaryan does that.
- The 6 patch series "samples/damon: handle damon_{start,stop}()
failures" from SJ Park fixes improper handling of damon_start(),
damon_stop(), and damon_call() failures across DAMON sample modules to
prevent potential memory leaks, operation disruptions and use-after-free
bugs.
- The 11 patch series "mm/damon/sysfs: kobject_del() directories that
users can create/remove" from SJ Park resolves an issue where delayed
sysfs directory removal under CONFIG_DEBUG_KOBJECT_RELEASE causes
creation failures due to duplicate directory names by adding missing
kobject_del() calls before creating new directories.
- The 3 patch series "mm: cleanup clear_not_present_full_ptes()" from
David Hildenbrand cleans up the core pte handling code.
- The 3 patch series "selftests/damon: misc fixes for test bugs" from
Kunwu Chan fixes several bugs in the DAMON selftests.
- The 2 patch series "selftests/damon: fix memcg_path staging handling"
from Cheng Nie fixes a bug in _damon_sysfs.py for damos_filter
memcg_path setup, and adds a test case for it in sysfs.py.
- The 2 patch series "selftests/damon: test kdamond refresh_ms" from
Ruslan Valiyev introduces selftest coverage for DAMON's refresh_ms sysfs
feature by updating the test control module and verifying that scheme
stats update automatically without manual intervention.
- The 5 patch series "mm/damon: five misc fixups" from Akinobu Mita
contains miscellaneous DAMON fixups.
- The 2 patch series "mm/damon/core: detect internal variation above
max_nr_regions/2" from Jiayuan Chen fixes DAMON's region splitting
behavior when region counts exceed half the maximum budget by
dynamically scaling down the split fraction as the limit approaches,
preventing large regions from staying un-split, and adds corresponding
KUnit test coverage.
- The 6 patch series "mm: preparatory patches for PMD level swap
entries" from Usama Arif refactors and cleans up PMD softleaf helpers,
call sites, and architecture flags to lay the groundwork for a follow-up
series that introduces PMD page table swap entries.
- The 11 patch series "mm/damon: update, optimize, and clean up doc,
tests, and code" from SJ Park updates DAMON design and ABI
documentation, expands unit and selftest coverage, optimizes
damon_commit_target_regions(), and cleans up recently added sysfs
interface code for better readability.
- The 2 patch series "mm/vmpressure: reduce CPU, memory and code
overhead on cgroup v2" from Usama Arif optimizes vmpressure() by
skipping unnecessary work on cgroup v2 for userspace event notifications
and refactors v1-only eventfd handling into mm/memcontrol-v1.c to reduce
memory overhead and code complexity.
- The 10 patch series "selftests/mm: refactor pkey helpers and fix mmap
error handling" from Hongfu Li refactors pkeys shared tracing and
assertion helpers into a common file, unifies protection key selftests
to use consistent diagnostic logging and assertions, and enforces
standardized MAP_FAILED return checks for mmap() calls across the tests.
- The 18 patch series "mm/damon: optimize out nr_accesses_bp" from SJ
Park replaces the error-prone, continuously updated nr_accesses_bp field
in damon_region with an on-demand moving sum function
(damon_nr_accesses_mvsum()), reducing structure memory overhead and
avoiding state corruption bugs.
- The 6 patch series "Open HugeTLB allocation routine for more generic
use" from Ackerley Tng decouples HugeTLB folio allocation from VMA
dependencies by introducing hugetlb_alloc_folio(), enabling subsystems
like guest_memfd to allocate HugeTLB folios without standard VMA
reservations or pseudo-VMAs.
- The 3 patch series "mm/damon: provide pseudo moving sum probe_hits"
from SJ Park integrates DAMON's probe_hits attribute counter into the
pseudo moving sum infrastructure, enabling real-time, online monitoring
without waiting for full aggregation intervals.
- The 18 patch series "mm: Some cleanups for page allocator APIs" from
Brendan Jackman simplifies and refactors the page allocator entry points
and flags by unifying allocation paths, adding internal alloc_flags
arguments, and eliminating redundant __ prefixed alloc_pages variants.
- The 5 patch series "Fix incorrect access of hugetlb pte entries" from
Dev Jain enforces the consistent use of huge_ptep_get() instead of
ptep_get() for HugeTLB entries and fixes an unaligned address issue in
arm64's huge_ptep_get() implementation.
- The 8 patch series "mm/damon: validate all parameters in the core"
from SJ Park consolidates parameter validation into the DAMON core
specifically within damon_start() and damon_commit_ctx() to centralize
error checking, eliminate caller-side redundant checks and to improve
maintenance efficiency.
- The 3 patch series "tools/mm/page_owner_sort: fix filtering and
cleanup issues" from Yichong Chen renames is_need() to filter_record()
for clearer return semantics, fixes per-record allocation memory leaks
and bounds output copies in search_pattern() to address an existing
buffer issue.
- The 4 patch series "memcg: bail out reclaim when memcg is dying" from
Jiayuan Chen mitigates a system-wide stall which occurs when a cgroup is
removed while one of its memory control files is doing synchronous
reclaim.
- The 5 patch series "mm/memory-failure: add panic option for
unrecoverable pages" from Breno Leitao introduces an opt-in
vm.panic_on_unrecoverable_memory_failure sysctl that immediately panics
the kernel on unrecoverable memory errors in kernel-owned pages to
preserve error context and prevent delayed, silent data corruption.
- The 11 patch series "mm/damon: refactor damon_{start,stop,commit}()
for simple error handling" from SJ Park refactors the DAMON core API
functions to guarantee that all contexts are fully stopped when
damon_start(), damon_stop(), or damon_commit() fail, eliminating the
need for complex and error-prone caller-side cleanup code.
- The 5 patch series "Keep tail page private zero at free and folio
split" from Zi Yan adds checks to ensure tail_page->private is zero when
freeing compound or high-order pages and when promoting tail pages
during large folio splits. By validating these fields at free and split
time, it allows the removal of redundant private field clearing inside
prep_compound_tail().
- The 4 patch series "mm: drop redundant lru_add_drain in anon folio
reuse paths" from Barry Song eliminates redundant lru_add_drain() calls
in wp_can_reuse_anon_folio() and do_swap_page() to reduce LRU lock
contention and system overhead.
By validating folio refcounts against the LRU cache before draining
and removing unnecessary drains in the swap path, it achieves up to a
30.5% reduction in drain calls during heavy swap workloads.
- The 3 patch series "mm: clean up folio LRU and swap declarations" from
Jianyue Wu reorganizes folio LRU and swap code by relocating
page-cluster state to mm/swap_state.c, renaming mm/swap.c to mm/folio.c,
and moving MM-internal reclaim declarations into mm/internal.h.
- The 15 patch series "userfaultfd: working set tracking for VM guest
memory" from Kiryl Shutsemau adds userfaultfd support for tracking the
working set of VM guest memory, so a VMM can identify hot pages and
reclaim cold ones to tiered or remote storage.
- The 10 patch series "mm: remove CONFIG_HAVE_BOOTMEM_INFO_NODE (Part
2)" from David Hildenbrand removes the remaining pieces of
CONFIG_HAVE_BOOTMEM_INFO_NODE, performing some smaller cleanups around
freeing of reserved vmemmap pages on the way.
- The 7 patch series "mm/damon: update probe hits for runtime parameter
commits" from SJ Park ensures that DAMON's probe_hits attribute counter
is properly updated when monitoring intervals are changed at runtime,
matching the behavior of nr_accesses. To achieve this, it refactors and
renames existing helper functions for shared use, applies the updates to
probe_hits, and handles edge cases in damon_probe_hits_mvsum() to
maintain measurement accuracy.
- The 3 patch series "KSM: performance optimizations for rmap_walk_ksm"
from xu xin resolves a severe KSM reverse-mapping performance bottleneck
where thousands of split VMAs sharing a single anon_vma cause extended
lock contention. By adding an interval-filtering check during the rmap
walk, it reduces worst-case anon_vma lock hold times from over 500ms
down to under 2ms, preventing application freezes and latency spikes
under memory pressure.
- The 3 patch series "mm: split a couple of headers from internal.h"
from Mike Rapoport splits declarations related to mm_init, memblock,
vmalloc and sparse into new headers.
- The 2 patch series "KSM: use linear_page_index in collect_procs_ksm()"
from xu xin applies the interval tree optimization from rmap_walk_ksm()
to collect_procs_ksm() to avoid iterating over non-matching VMAs during
KSM memory error handling. It hoists loop-invariant address
initialization and restricts the anon_vma_interval_tree_foreach walk to
a targeted page offset range, reducing redundant checks and improving
lookup efficiency.
- The 3 patch series "selftests/mm: avoid false failures in hugetlb and
KSM tests" from Sayali Patil fixes issues in the hugetlb and KSM MM
selftest categories that can report failures when the prerequisites for
the tests are not satisfied.
- The 19 patch series "mm/damon: introduce data attributes only
monitoring" from SJ Park introduces attribute-weighted region management
in DAMON, allowing users to prioritize specific data attributes (such as
page sizes or cgroups) over or instead of access monitoring.
By assigning weights to attribute probes, DAMON can completely disable
access tracking and adjust monitoring regions based on weighted
probe-hit counters to optimize monitoring quality for attribute-focused
workloads.
- The 8 patch series "mm/hmm: Add mmap lock-drop support for
userfaultfd-backed mappings" from Stanislav Kinsburskii extends
hmm_range_fault() to support userfaultfd-backed regions by allowing the
mmap lock to be dropped during fault handling via a new
hmm_range_fault_locked() helper.
By accepting a locked pointer and signaling retry status when lock
release occurs, it enables page fault resolution in userfaultfd regions
while preserving backward compatibility for existing callers.
- The 33 patch series "mm: make VMA page offset handling more
consistent" from Lorenzo Stoakes cleans up and standardizes how
vma->vm_pgoff is accessed and manipulated across file-backed and
anonymous mappings in the kernel.
It introduces dedicated helper functions such as vma_start_pgoff(),
vma_end_pgoff(), vma_set_pgoff() and linear_page_delta() while renaming
rmap interval tree helpers to better reflect their functionality.
These changes establish a cleaner foundation for future work that will
unify virtual page offset indexing for all anonymous and CoW'd folios.
- The 3 patch series "mm: handle device-private PMDs in walk callbacks"
from Usama Arif addresses kernel panics and state corruption caused by
MM walk callbacks reaching non-present device-private PMD swap entries
created during HMM migrations.
It ensures that functions which acquire pmd_trans_huge_lock() properly
recognize device-private PMDs instead of assuming a present THP or a
standard migration entry.
- The 5 patch series "mm/rmap: Refactor try_to_unmap_one" from Dev Jain
refactors try_to_unmap_one by modularizing Hugetlb, anonymous-lazyfree,
and anonymous-swapbacked logic into dedicated functions, laying the
structural groundwork for batched anonymous large folio unmapping.
- The 4 patch series "Docs/ABI/damon: sysfs ABI document fixes and
additions" from Song Hu fixes typos and fills in missing entries in the
DAMON sysfs ABI document.
- The 10 patch series "dax/kmem: atomic whole-device hotplug via sysfs"
from Gregory Price introduces an atomic sysfs state attribute and
supporting DAX/MM infrastructure to prevent userland races when
offlining and removing entire memory regions.
By adding an unplugged state alongside standard online modes, it
enables whole-device atomic hotplug control while preserving backward
compatibility.
- The 13 patch series "mm: convert more vm_flags_t users to vma_flags_t"
from Lorenzo Stoakes continues transitioning the kernel from the
deprecated vm_flags_t type to vma_flags_t across core memory management
infrastructure.
It replaces legacy type usage in core functions such as do_mmap(),
unmapped area allocation, mm->def_vma_flags, and VMA operations like
mlock, mprotect, and mremap.
- The 2 patch series "Two small patches to clean up mm/mm_slot.h" from
xu xin refactors mm_slot.h by introducing mm_slot_remove() to unify
duplicate slot deletion sequences in khugepaged and KSM. It also adds
code documentation explaining why mm_slot_lookup and mm_slot_insert must
remain as preprocessor macros rather than static inline functions.
- The 10 patch series "mm/damon/core: hide core-private struct fields"
from SJ Park cleans up DAMON core structures by consistently marking
internal-only fields with private: comment tags to prevent improper
direct access from outer layers.
It enforces encapsulation across core structures including
damon_region, damon_target, and damon_ctx and updates DAMON_SYSFS to
interact through approved access APIs instead of exposing raw struct
members.
- The 6 patch series "mm/damon: unurgent fixes for infinite loop, NULL
de-ref and races" from SJ Park addresses potential infinite loops, NULL
dereferences, and race conditions identified in DAMON.
It fixes an infinite loop triggered by extreme user configurations, a
NULL pointer dereference within unit tests and minor monitoring
accuracy degradation caused by subtle runtime races.
- The 2 patch series "mm/page_alloc: fixes for free_pages_nolock() on
RT/UP" from Brendan Jackman fixes an NMI safety flaw in
__free_frozen_pages() where freeing pages on non-SMP or PREEMPT_RT
kernels can bypass can_spin_trylock() checks via non-PCP or isolated
migration paths.
It also resolves potential kernel crashes and privilege escalation
risks triggered when BPF tracing runs in NMI context alongside memory
hotplug or large allocation frees.
- The 4 patch series "mm/page_alloc: couple of followups for recent
cleanups" from Brendan Jackman cleans up and updates page allocator
nomenclature, documentation, and debug assertions.
It aligns internal FPI_ flags with the public "nolock" naming
convention, removes outdated internal implementation details from
high-level page allocator comments, and eliminates obsolete VM_BUG_ON()
assertions in allocation paths.
- The 3 patch series "mm/mseal: further cleanups" from Lorenzo Stoakes
refactors and simplifies the mseal implementation by clarifying API
boundaries and removing unnecessary code complexity.
It replaces generic do_mseal() usage outside the syscall with a
dedicated mseal_mmap_page_zero() helper for MMAP_PAGE_ZERO, eliminates
mm_struct parameters to enforce that sealing applies only to
current->mm, and streamlines overall logic and comments with no
functional changes intended.
- The 4 patch series "mm/vmscan: fix swappiness=max and clean up
per-node proactive reclaim" from Ridong Chen resolves reclaim behavior
bugs and cleans up function parameters across memory reclaim paths.
It fixes swappiness=max in both standard reclaim and MGLRU so
unswappable anonymous memory no longer falls back to evicting page
cache, ensures reclaim_store() returns accurate error codes instead of
collapsing all failures into -EAGAIN, and removes the obsolete gfp_mask
parameter from __node_reclaim().
- The 6 patch series "mm: mincore: misc cleanups" from Kefeng Wang
cleans up and simplifies the mincore code. Most importantly, it removes
the historical special behavior that always reports VM_PFNMAP pages as
non-resident.
- The 2 patch series "mm/huge_memory: drop dead split helper variants"
from Kiryl Shutsemau implements two trivial cleanups in the folio split
API.
- The 7 patch series "mm/damon: fix uninitialized DAMOS field and kunit
exec expectation bugs" from SJ Park resolves minor operational and
testing bugs in DAMON identified by Sashiko. It initializes the
damos->last_applied field to prevent occasional efficiency degradation
and fixes invalid memory accesses in DAMON KUnit tests during test
failure handling.
- The 3 patch series "cleanup for stable_page_flags()" from Jinjiang Tu
cleans up and refactors stable_page_flags() used by /proc/kpageflags
without altering functionality.
It uses BIT_ULL() to prevent shift-overflow warnings on 64-bit flag
bits, converts folio-specific flag checks to standard folio_test_*()
helpers, and removes redundant CONFIG_PAGE_IDLE_FLAG handling.
- The 3 patch series "Batch unmap of uffd-wp file folios" from Dev Jain
extends batched folio unmapping support to file folios within
userfaultfd write-protect (uffd-wp) VMAs by adding batching capabilities
to pte_install_uffd_wp_if_needed().
This removes special-case restrictions on uffd-wp VMAs in
try_to_unmap_one(), significantly simplifying the function's control
flow and complexity.
- The 3 patch series "mm/early_ioremap: clarify and clean up
early_ioremap_reset()" from Sang-Heon Jeon clarifies and cleans up the
architecture-specific usage of __late_set_fixmap() and
__late_clear_fixmap() after early_ioremap_reset().
It adds explicit documentation regarding when early_ioremap_reset()
must be called and removes redundant macro definitions and reset calls
in the RISC-V and ARM64 architectures.
- The 4 patch series "mm: fix reclaim storms in defrag_mode" from
Johannes Weiner addresses severe performance regressions, swap storms,
and spurious OOMs caused by vm.defrag_mode=1 under high memory pressure
in Meta production.
It updates the page allocator slowpath so non-movable allocation
requests actively trigger direct reclaim and direct compaction at
pageblock_order scale, allowing them to claim whole pageblocks rather
than spinning unproductively.
- The 2 patch series "zram: lockmap tweaks" from Sebastian Siewior
optimizes and fixes lockdep tracking for zram devices by consolidating
per-entry lockmaps and isolating lock classes across multiple instances.
It reduces memory overhead by replacing per-entry lockdep_map instances
with a single map per struct zram, and assigns a dynamic lock_class_key
to each instance to prevent false deadlock reports when different zram
devices are backed by distinct filesystems.
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQTTMBEPP41GrTpTJgfdBJ7gKXxAjgUCaoUJbQAKCRDdBJ7gKXxA
jqrzAP9WoPU0hiK4qS/kSjhtoZxhjpS5eLSUCy/utKuEvZbfGgEAu1zA+LH+X9Tm
THK5ex4iUZxiFbXpWfLMxE/Q9PmQYQ8=
=QTyb
-----END PGP SIGNATURE-----
Merge tag 'mm-stable-2026-08-18-18-39' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull MM updates from Andrew Morton:
- "mm: drop "sub" prefix from various places" (Dev Jain)
page->folio conversion and a naming cleanup
- "mm/kasan: remove redundant initialization for kasan_flag_write_only"
(Igor Putko)
KASAN cleanup work
- "mm/filemap: reduce unnecessary xarray lookups" (Chi Zhiling)
Small speedup in the pagecaache read code
- "mm/percpu: Fix possible NOFS/NOIO reclaim recursion" (Kaitao Cheng)
Improve the vmalloc code - mainly the avoidance of GFP_KERNEL
allocations when the caller asked for GFP_NOFS or GFP_NOIO
- "mm/kmemleak: avoid soft lockup when scanning task stacks" (Breno
Leitao)
Avoid a soft lockup watchdog trigger from the kmemleak scanning code
in extreme situations
- "mm/page_owner: misc cleanups" (Ye Liu)
Cleanups to the page_owner code. For some reason lots of people have
been working on the page_owner code this cycle.
- "mm: convert to walk_page_range_vma() to eliminate find_vma()"
(Kefeng Wang)
Simplify and accelerate the page walking library function
- "mm/migrate: preparatory cleanups for batch copy and offload"
(Shivank Garg)
Cleanups in the migration code
- "mm/page_owner: add per-fd filter infrastructure for print_mode and
NUMA filtering" (Zhen Ni)
Per-fd filtering to page_owner in order to reduce the sometimes vast
amount of output it can produce
- "mm: Refactor bootmem gigantic hugepage allocation" (Muchun Song)
Fixes and preparatory cleanups around bootmem HugeTLB handling,
sparse initialization ordering, and related vmemmap setup
- "mm/zsmalloc: reduce lock contention in zs_free()" (Wenchao Hao)
Reduce lock contention in zs_free(), which dominates the unmap path
under memory pressure on Android (LMK kills) and on x86 servers
running zswap-heavy workloads.
Up to 1.83x improvement in microbenchmarking.
- "move alloc_tag.c file under mm/" (Suren Baghdasaryan)
- "samples/damon: handle damon_{start,stop}() failures" (SJ Park)
Fix improper handling of damon_start(), damon_stop(), and
damon_call() failures across DAMON sample modules to prevent
potential memory leaks, operation disruptions and use-after-free
bugs
- "mm/damon/sysfs: kobject_del() directories that users can
create/remove" (SJ Park)
Fix delayed sysfs directory removal under DEBUG_KOBJECT_RELEASE
causeing creation failures due to duplicate directory names by adding
missing kobject_del() calls before creating new directories
- "mm: cleanup clear_not_present_full_ptes()" (David Hildenbrand)
Clean up the core pte handling code
- "selftests/damon: misc fixes for test bugs" (Kunwu Chan)
Fix several bugs in the DAMON selftests
- "selftests/damon: fix memcg_path staging handling" (Cheng Nie)
Fix a bug in _damon_sysfs.py for damos_filter memcg_path setup, and
add a test case for it in sysfs.py.
- "selftests/damon: test kdamond refresh_ms" (Ruslan Valiyev)
Selftest coverage for DAMON's refresh_ms sysfs feature by updating
the test control module and verifying that scheme stats update
automatically without manual intervention
- "mm/damon: five misc fixups" (Akinobu Mita)
Miscellaneous DAMON fixups.
- "mm/damon/core: detect internal variation above max_nr_regions/2"
(Jiayuan Chen)
Fix DAMON's region splitting behavior when region counts exceed half
the maximum budget by dynamically scaling down the split fraction as
the limit approaches, preventing large regions from staying un-split,
and add corresponding KUnit test coverage
- "mm: preparatory patches for PMD level swap entries" (Usama Arif)
Refactor and clean up PMD softleaf helpers, call sites, and
architecture flags to lay the groundwork for a follow-up series that
introduces PMD page table swap entries
- "mm/damon: update, optimize, and clean up doc, tests, and code" (SJ
Park)
Update DAMON design and ABI documentation, expands unit and selftest
coverage, optimize damon_commit_target_regions(), and clean up
recently added sysfs interface code for better readability
- "mm/vmpressure: reduce CPU, memory and code overhead on cgroup v2"
(Usama Arif)
Optimize vmpressure() by skipping unnecessary work on cgroup v2 for
userspace event notifications and refactor v1-only eventfd handling
into mm/memcontrol-v1.c to reduce memory overhead and code complexity
- "selftests/mm: refactor pkey helpers and fix mmap error handling"
(Hongfu Li)
Refactor pkeys shared tracing and assertion helpers into a common
file, unify protection key selftests to use consistent diagnostic
logging and assertions, and enforce standardized MAP_FAILED return
checks for mmap() calls across the tests
- "mm/damon: optimize out nr_accesses_bp" (SJ Park)
Replace the error-prone, continuously updated nr_accesses_bp field in
damon_region with an on-demand moving sum function, reducing
structure memory overhead and avoiding state corruption bugs
- "Open HugeTLB allocation routine for more generic use" (Ackerley Tng)
Decouple HugeTLB folio allocation from VMA dependencies by
introducing hugetlb_alloc_folio(), enabling subsystems like
guest_memfd to allocate HugeTLB folios without standard VMA
reservations or pseudo-VMAs
- "mm/damon: provide pseudo moving sum probe_hits" (SJ Park)
Integrate DAMON's probe_hits attribute counter into the pseudo moving
sum infrastructure, enabling real-time, online monitoring without
waiting for full aggregation intervals
- "mm: Some cleanups for page allocator APIs" (Brendan Jackman)
Simplify and refactor the page allocator entry points and flags by
unifying allocation paths, adding internal alloc_flags arguments, and
eliminating redundant __ prefixed alloc_pages variants.
- "Fix incorrect access of hugetlb pte entries" (Dev Jain)
Enforce the consistent use of huge_ptep_get() instead of ptep_get()
for HugeTLB entries and fixes an unaligned address issue in arm64's
huge_ptep_get() implementation
- "mm/damon: validate all parameters in the core" (SJ Park)
Consolidate parameter validation into the DAMON core specifically
within damon_start() and damon_commit_ctx() to centralize error
checking, eliminate caller-side redundant checks and to improve
maintenance efficiency
- "tools/mm/page_owner_sort: fix filtering and cleanup issues" (Yichong
Chen)
Rename is_need() to filter_record() for clearer return semantics, fix
per-record allocation memory leaks and bound output copies in
search_pattern() to address an existing buffer issue
- "memcg: bail out reclaim when memcg is dying" (Jiayuan Chen)
Mitigate a system-wide stall which occurs when a cgroup is removed
while one of its memory control files is doing synchronous reclaim
- "mm/memory-failure: add panic option for unrecoverable pages" (Breno
Leitao)
Introduce an opt-in vm.panic_on_unrecoverable_memory_failure sysctl
that immediately panics the kernel on unrecoverable memory errors in
kernel-owned pages to preserve error context and prevent delayed,
silent data corruption
- "mm/damon: refactor damon_{start,stop,commit}() for simple error
handling" (SJ Park)
Refactor the DAMON core API functions to guarantee that all contexts
are fully stopped when damon_start(), damon_stop(), or damon_commit()
fail, eliminating the need for complex and error-prone caller-side
cleanup code
- "Keep tail page private zero at free and folio split" (Zi Yan)
Add checks to ensure tail_page->private is zero when freeing compound
or high-order pages and when promoting tail pages during large folio
splits. By validating these fields at free and split time, it allows
the removal of redundant private field clearing inside
prep_compound_tail()
- "mm: drop redundant lru_add_drain in anon folio reuse paths" (Barry
Song)
Eliminate redundant lru_add_drain() calls in
wp_can_reuse_anon_folio() and do_swap_page() to reduce LRU lock
contention and system overhead
By validating folio refcounts against the LRU cache before draining
and removing unnecessary drains in the swap path, it achieves up to a
30.5% reduction in drain calls during heavy swap workloads
- "mm: clean up folio LRU and swap declarations" (Jianyue Wu)
Reorganize folio LRU and swap code by relocating page-cluster state
to mm/swap_state.c, renaming mm/swap.c to mm/folio.c, and moving
MM-internal reclaim declarations into mm/internal.h.
- "userfaultfd: working set tracking for VM guest memory" (Kiryl
Shutsemau)
Add userfaultfd support for tracking the working set of VM guest
memory, so a VMM can identify hot pages and reclaim cold ones to
tiered or remote storage
- "mm: remove CONFIG_HAVE_BOOTMEM_INFO_NODE (Part 2)" (David
Hildenbrand)
Remove the remaining pieces of CONFIG_HAVE_BOOTMEM_INFO_NODE,
performing some smaller cleanups around freeing of reserved vmemmap
pages on the way.
- "mm/damon: update probe hits for runtime parameter commits" (SJ Park)
Ensure that DAMON's probe_hits attribute counter is properly updated
when monitoring intervals are changed at runtime, matching the
behavior of nr_accesses. To achieve this, it refactors and renames
existing helper functions for shared use, applies the updates to
probe_hits, and handles edge cases in damon_probe_hits_mvsum() to
maintain measurement accuracy.
- "KSM: performance optimizations for rmap_walk_ksm" (xu xin)
Resolve a severe KSM reverse-mapping performance bottleneck where
thousands of split VMAs sharing a single anon_vma cause extended lock
contention.
By adding an interval-filtering check during the rmap walk, it
reduces worst-case anon_vma lock hold times from over 500ms down to
under 2ms, preventing application freezes and latency spikes under
memory pressure.
- "mm: split a couple of headers from internal.h" (Mike Rapoport)
Split declarations related to mm_init, memblock, vmalloc and sparse
into new headers
- "KSM: use linear_page_index in collect_procs_ksm()" (xu xin)
Apply the interval tree optimization from rmap_walk_ksm() to
collect_procs_ksm() to avoid iterating over non-matching VMAs during
KSM memory error handling.
It hoists loop-invariant address initialization and restricts the
anon_vma_interval_tree_foreach walk to a targeted page offset range,
reducing redundant checks and improving lookup efficiency.
- "selftests/mm: avoid false failures in hugetlb and KSM tests" (Sayali
Patil)
Fix issues in the hugetlb and KSM MM selftest categories that can
report failures when the prerequisites for the tests are not
satisfied
- "mm/damon: introduce data attributes only monitoring" (SJ Park)
Introduce attribute-weighted region management in DAMON, allowing
users to prioritize specific data attributes (such as page sizes or
cgroups) over or instead of access monitoring.
By assigning weights to attribute probes, DAMON can completely
disable access tracking and adjust monitoring regions based on
weighted probe-hit counters to optimize monitoring quality for
attribute-focused workloads.
- "mm/hmm: Add mmap lock-drop support for userfaultfd-backed mappings"
(Stanislav Kinsburskii)
Extend hmm_range_fault() to support userfaultfd-backed regions by
allowing the mmap lock to be dropped during fault handling via a new
hmm_range_fault_locked() helper.
By accepting a locked pointer and signaling retry status when lock
release occurs, it enables page fault resolution in userfaultfd
regions while preserving backward compatibility for existing callers.
- "mm: make VMA page offset handling more consistent" (Lorenzo Stoakes)
Clean up and standardize how vma->vm_pgoff is accessed and
manipulated across file-backed and anonymous mappings in the kernel
It introduces dedicated helper functions such as vma_start_pgoff(),
vma_end_pgoff(), vma_set_pgoff() and linear_page_delta() while
renaming rmap interval tree helpers to better reflect their
functionality.
These changes establish a cleaner foundation for future work that
will unify virtual page offset indexing for all anonymous and CoW'd
folios.
- "mm: handle device-private PMDs in walk callbacks" (Usama Arif)
Address kernel panics and state corruption caused by MM walk
callbacks reaching non-present device-private PMD swap entries
created during HMM migrations
It ensures that functions which acquire pmd_trans_huge_lock()
properly recognize device-private PMDs instead of assuming a present
THP or a standard migration entry.
- "mm/rmap: Refactor try_to_unmap_one" (Dev Jain)
Refactor try_to_unmap_one by modularizing Hugetlb,
anonymous-lazyfree, and anonymous-swapbacked logic into dedicated
functions, laying the structural groundwork for batched anonymous
large folio unmapping.
- "Docs/ABI/damon: sysfs ABI document fixes and additions" (Song Hu)
Fix typos and fills in missing entries in the DAMON sysfs ABI
document
- "dax/kmem: atomic whole-device hotplug via sysfs" (Gregory Price)
Introduce an atomic sysfs state attribute and supporting DAX/MM
infrastructure to prevent userland races when offlining and removing
entire memory regions
By adding an unplugged state alongside standard online modes, it
enables whole-device atomic hotplug control while preserving backward
compatibility.
- "mm: convert more vm_flags_t users to vma_flags_t" (Lorenzo Stoakes)
Continue transitioning the kernel from the deprecated vm_flags_t type
to vma_flags_t across core memory management infrastructure.
It replaces legacy type usage in core functions such as do_mmap(),
unmapped area allocation, mm->def_vma_flags, and VMA operations like
mlock, mprotect, and mremap.
- "Two small patches to clean up mm/mm_slot.h" (xu xin)
Refactor mm_slot.h by introducing mm_slot_remove() to unify duplicate
slot deletion sequences in khugepaged and KSM. It also adds code
documentation explaining why mm_slot_lookup and mm_slot_insert must
remain as preprocessor macros rather than static inline functions.
- "mm/damon/core: hide core-private struct fields" (SJ Park)
Clean up DAMON core structures by consistently marking internal-only
fields with private: comment tags to prevent improper direct access
from outer layers.
It enforces encapsulation across core structures including
damon_region, damon_target, and damon_ctx and updates DAMON_SYSFS to
interact through approved access APIs instead of exposing raw struct
members.
- "mm/damon: unurgent fixes for infinite loop, NULL de-ref and races"
(SJ Park)
Address potential infinite loops, NULL dereferences, and race
conditions identified in DAMON
It fixes an infinite loop triggered by extreme user configurations, a
NULL pointer dereference within unit tests and minor monitoring
accuracy degradation caused by subtle runtime races.
- "mm/page_alloc: fixes for free_pages_nolock() on RT/UP" (Brendan
Jackman)
Fix an NMI safety flaw in __free_frozen_pages() where freeing pages
on non-SMP or PREEMPT_RT kernels can bypass can_spin_trylock() checks
via non-PCP or isolated migration paths.
It also resolves potential kernel crashes and privilege escalation
risks triggered when BPF tracing runs in NMI context alongside memory
hotplug or large allocation frees.
- "mm/page_alloc: couple of followups for recent cleanups" (Brendan
Jackman)
Clean up and update page allocator nomenclature, documentation, and
debug assertions.
It aligns internal FPI_ flags with the public "nolock" naming
convention, removes outdated internal implementation details from
high-level page allocator comments, and eliminates obsolete
VM_BUG_ON() assertions in allocation paths.
- "mm/mseal: further cleanups" (Lorenzo Stoakes)
Refactor and simplify the mseal implementation by clarifying API
boundaries and removing unnecessary code complexity.
It replaces generic do_mseal() usage outside the syscall with a
dedicated mseal_mmap_page_zero() helper for MMAP_PAGE_ZERO,
eliminates mm_struct parameters to enforce that sealing applies only
to current->mm, and streamlines overall logic and comments with no
functional changes intended.
- "mm/vmscan: fix swappiness=max and clean up per-node proactive
reclaim" (Ridong Chen)
Resolve reclaim behavior bugs and clean up function parameters across
memory reclaim paths
It fixes swappiness=max in both standard reclaim and MGLRU so
unswappable anonymous memory no longer falls back to evicting page
cache, ensures reclaim_store() returns accurate error codes instead
of collapsing all failures into -EAGAIN, and removes the obsolete
gfp_mask parameter from __node_reclaim().
- "mm: mincore: misc cleanups" (Kefeng Wang)
Clean up and simplifies the mincore code. Most importantly, it
removes the historical special behavior that always reports VM_PFNMAP
pages as non-resident.
- "mm/huge_memory: drop dead split helper variants" (Kiryl Shutsemau)
Two trivial cleanups in the folio split API
- "mm/damon: fix uninitialized DAMOS field and kunit exec expectation
bugs" (SJ Park)
Resolve minor operational and testing bugs in DAMON identified by
Sashiko. It initializes the damos->last_applied field to prevent
occasional efficiency degradation and fixes invalid memory accesses
in DAMON KUnit tests during test failure handling.
- "cleanup for stable_page_flags()" (Jinjiang Tu)
Clean up and refactor stable_page_flags() used by /proc/kpageflags
without altering functionality.
It uses BIT_ULL() to prevent shift-overflow warnings on 64-bit flag
bits, converts folio-specific flag checks to standard folio_test_*()
helpers, and removes redundant CONFIG_PAGE_IDLE_FLAG handling.
- "Batch unmap of uffd-wp file folios" (Dev Jain)
Extend batched folio unmapping support to file folios within
userfaultfd write-protect (uffd-wp) VMAs by adding batching
capabilities to pte_install_uffd_wp_if_needed().
This removes special-case restrictions on uffd-wp VMAs in
try_to_unmap_one(), significantly simplifying the function's control
flow and complexity.
- "mm/early_ioremap: clarify and clean up early_ioremap_reset()"
(Sang-Heon Jeon)
Clarify and clean up the architecture-specific usage of
__late_set_fixmap() and __late_clear_fixmap() after
early_ioremap_reset()
It adds explicit documentation regarding when early_ioremap_reset()
must be called and removes redundant macro definitions and reset
calls in the RISC-V and ARM64 architectures.
- "mm: fix reclaim storms in defrag_mode" (Johannes Weiner)
Address severe performance regressions, swap storms, and spurious
OOMs caused by vm.defrag_mode=1 under high memory pressure in Meta
production
It updates the page allocator slowpath so non-movable allocation
requests actively trigger direct reclaim and direct compaction at
pageblock_order scale, allowing them to claim whole pageblocks rather
than spinning unproductively.
- "zram: lockmap tweaks" (Sebastian Siewior)
Optimize and fix lockdep tracking for zram devices by consolidating
per-entry lockmaps and isolate lock classes across multiple instances
This reduces memory overhead by replacing per-entry lockdep_map
instances with a single map per struct zram, and assigns a dynamic
lock_class_key to each instance to prevent false deadlock reports
when different zram devices are backed by distinct filesystems.
* tag 'mm-stable-2026-08-18-18-39' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (501 commits)
selftests/mm: thuge-gen: fix test_shmget() for PAGE_SIZE check
selftests/mm: unpoison pages in memory-failure teardown
mm/shmem: downgrade final i_blocks check in shmem_evict_inode() to pr_warn()
mm/khugepaged: replace mutex_lock/mutex_unlock usage with guard macro
mm/zsmalloc: fix release order of locks in zs_page_migrate()
Documentation: zram: remove sections numbering
ksm: stop iterating VMAs when ksm_test_exit returns true
mm: fold userfaultfd_rwp() to false without CONFIG_ARCH_HAS_PTE_PROTNONE
mm/migrate: report RCU-tasks quiescent states in migrate_pages_batch()
zram: use a custom key for each zram object
zram: move lockmap to be per-zram instead per table
selftests/mm: fix gup_longterm EINVAL error message
mm: page_alloc: fix non-movable reclaim storm in defrag_mode
mm: page_alloc: move capture_control to the page allocator
mm: compaction: support non-movable compaction for pageblock requests
mm: page_alloc: __GFP_FS lockdep annotation for direct compaction
hugetlb: evaluate subpool free state while locked
mm/damon: remove trailing semicolons after function definitions
mm/damon/ops-common: prevent migration fallback to non-target nodes
mm/damon: update outdated comment about DAMOS filter handling
...
|
||
|
|
9a9ee7408a |
f2fs: reduce memory footprint of ino management
Currently, ino entries for APPEND_INO, UPDATE_INO, TRANS_DIR_INO, and
XATTR_DIR_INO allocate a 'struct ino_entry' slab object and attach it to
both a list and a radix tree solely for existence checks via
f2fs_exist_written_data().
Since these ino types only track binary existence status, we can embed
the information directly into radix tree value entries as a bitmap:
- The Linux radix tree/XArray supports in-place value entries via
xa_mk_value() / xa_to_value(), which tag the least significant bit
to store an unallocated integer value of BITS_PER_XA_VALUE bits
(BITS_PER_LONG - 1) directly in the slot pointer.
- For each inode, (ino / BITS_PER_XA_VALUE) serves as the radix tree
slot index, and (ino % BITS_PER_XA_VALUE) is used as the bit offset
within the slot's bitmap.
For example, when tracking ino = 7:
- Before: Allocate a 'struct ino_entry' ({ .ino = 7 }), insert its
pointer into the radix tree at index = 7, and link it to im->ino_list.
- After: Compute slot_index = 7 / BITS_PER_XA_VALUE (index 0) and
bit_offset = 7 % BITS_PER_XA_VALUE (bit 7), then set bit 7 in the
value entry via xa_mk_value(bitmap) at index 0, without allocating
a slab object or linking to a list.
Additionally:
- In-place slot updates are performed via radix_tree_replace_slot(), and
slots are deleted with radix_tree_delete() once the bitmap is zeroed.
- Reorder the ino list enum so ORPHAN_INO and FLUSH_INO (which still
require struct ino_entry and list traversal) remain separated, while
bitmap-based trees are torn down using xa_destroy().
This eliminates 'struct ino_entry' slab allocations and linked-list
tracking for these ino types, significantly reducing memory consumption.
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
|
||
|
|
0f448bb376 |
f2fs: fix i_size when pinned fallocate partially fails
From: Zhan Xusheng <zhanxusheng@xiaomi.com> Commit |
||
|
|
8ec06f50dd |
f2fs: fix to migrate all curseg types during free_segment_range
In free_segment_range(), the curseg evacuation loop only iterates up to
NR_CURSEG_PERSIST_TYPE (0..5), missing non-persistent in-memory curseg
types such as CURSEG_COLD_DATA_PINNED and CURSEG_ALL_DATA_ATGC.
Even though these in-memory curseg types are not saved in the on-disk
checkpoint header, they still occupy active physical segments at runtime.
If an active in-memory curseg happens to be allocated within the segment
range being truncated during filesystem shrink, failing to evacuate it
will cause subsequent writes to the curseg attempting out-of-bounds I/O
on the truncated storage range.
Fix this by expanding the curseg evacuation loop upper bound to
NR_CURSEG_TYPE to ensure all active curseg types are safely migrated
out of the target range.
Fixes:
|
||
|
|
258c95150c |
f2fs: avoid setting SBI_NEED_FSCK on transient resize failure
When free_segment_range() fails in f2fs_resize_fs(), no on-disk superblock or filesystem metadata has been modified yet, and free_segment_range() safely restores all in-memory counters before returning. However, the current error recovery path unconditionally sets the SBI_NEED_FSCK flag and prints a scary error message on any error, forcing an unnecessary and time-consuming fsck.f2fs repair on the subsequent mount/reboot. Fix this by separating the error recovery path with a dedicated recover_user_blocks label to bypass setting SBI_NEED_FSCK on free_segment_range() failures. Signed-off-by: Daeho Jeong <daehojeong@google.com> Signed-off-by: Sunmin Jeong <s_min.jeong@samsung.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> |
||
|
|
ee5a386cfe |
NFSv4.1: fix layout segment leak on the pnfs_layout_process() forget path
When the server returns a new layout stateid while a valid one is still held, pnfs_layout_process() calls pnfs_mark_matching_lsegs_return() on the on-stack free_me list and jumps to out_forget. Segments whose reference count drops to zero are unlinked from lo->plh_segs and moved to free_me by mark_lseg_invalid(); for an idle cached segment the layout header holds the only reference, so this happens on the first decrement. out_forget never drains free_me -- only the success path calls pnfs_free_lseg_list(). Commit |
||
|
|
13c23c5cb9 |
NFSv4/pnfs: key the data server cache on the NFS version
nfs4_pnfs_ds_add() keys the per-net data server cache on the multipath
address set alone, and struct nfs4_pnfs_ds records no version. That
suffices for the files layout driver, which always connects with version
4, but flexfiles takes its version tuple from GETDEVICEINFO per device,
and one address can legitimately serve both NFSv3 and NFSv4.
Two deviceids on one address with different ds_versions[0].version
therefore share a single nfs4_pnfs_ds, and whichever mirror connects
first pins ds_clp to its own version. The other one is handed that
client anyway, so it selects rpc_call_ops for a version the connection
does not speak, and the mismatched sequence-slot handling dereferences
NULL.
Add the version to the cache key so the two cannot alias, giving each
version its own nfs4_pnfs_ds and connection while both mirrors stay
usable. Only the major version is compared, since that is what selects
rpc_call_ops and rpc_ops; v4.0 and v4.1 keep sharing a client. The files
layout driver passes the 4 it already hardcodes at connect time.
Fixes:
|
||
|
|
2035820177 |
pNFS: Fix EBUSY check in pnfs_layout_need_return
Commit |
||
|
|
8fa4804fe6 |
NFSv4.1: zero referring call lists before decoding
decode_cb_sequence_args() allocates csa_rclists with kmalloc_objs(), so
each referring_call_list starts uninitialized. decode_rc_list() assigns
rcl_refcalls only when rcl_nrefcalls is nonzero. A valid list with zero
referring calls therefore leaves the pointer uninitialized, and
nfs4_callback_sequence() later passes stale slab contents to kfree().
Allocate csa_rclists with kzalloc_objs() so every rcl_refcalls member is
NULL from the beginning, including valid empty referring call lists.
Fixes:
|
||
|
|
55ab7e1422 |
for-7.3/block-20260819
-----BEGIN PGP SIGNATURE-----
iQJEBAABCAAuFiEEwPw5LcreJtl1+l5K99NY+ylx4KYFAmqGD2AQHGF4Ym9lQGtl
cm5lbC5kawAKCRD301j7KXHgpomLD/9rr3SIQvdQRTnSCJlw1cFypSrnRhGAx1g8
v1F7UXuf4Abt4GIerbdXmBTx9zZRctpcOC41ReQk3YKkYuukuvna+Z6tBGf5I5+e
3SR3Zkrj2k4zyNC49g0/QkUJkTTS4tlsBFhNJtY3Q5BBIRMRd/sPvZ+cLnD7g/wH
3zM9IaEMk9xu9mF1nGI7LRl1qY0IOr4ynQpqohl5sEL3TQWgIa0r2B0jhGacBAvC
GGDwIwGDrM6oGwCn6mLN78O5odhLyTufIMNy3EnVw7BcDpLApcnJzYYjGzv+ElCM
WLBJwWYj+PYeoenuJuFhbRihbOPg5gZT3Mn8CUhLxUYzwZvIdFGWOjcGffD9sVu/
JO4nB6A+2AG/wgsb2YVKefhN86FoD0F/2hhdEdgZPJE6a+7+xeyyp9IzyQEWd0cg
Seo06fxE4pwF+dczXT3jzU3LXSZb/Jbh9hzu163VMSWbGYDCpDzfipqZGeN6DWE7
nG2NssAQtjtZrgdggYbZXtwecLZhu3cMj3jbhS4wSUzhQFW42yceJstCx4wpRhW9
m9EXjHQnRFMAb2TjUC3FzEncjbxL+uACjcKhTetd1hLbTI5I8KArZXjam1OdJOHV
urdtsru79LanQLAgRwWYPeKCZGNhX7I2o3OsmVDLQgHIDaZguTcPUVQs3wVui7Dk
IDmmrtwzpg==
=G1l4
-----END PGP SIGNATURE-----
Merge tag 'for-7.3/block-20260819' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux
Pull block updates from Jens Axboe:
- NVMe updates via Keith:
- Enable Clang context analysis for the nvme host driver, adding
context annotations across core, fabrics, rdma, tcp and pci
- nvmet reservation state exposed through a new namespace-level
debugfs directory, plus ABI documentation for the host sysfs and
target configfs interfaces
- nvme-tcp host memory disclosure fixes on the read path: reject a
read that transferred too few bytes, don't accept C2HData based
on blk_rq_payload_bytes() alone, and fix the R2T case for a read
command
- Parallelize nvme-rdma I/O queue allocation and startup (Surabhi)
- Apple nvme fixes and quirks: page aligned admin queue buffers,
destroy the admin queue on removal, and various DMA/NVMMU
correctness fixes
- A large pile of nvmet and host fixes for out-of-bounds reads,
refcount/resource leaks, and NULL derefs across auth, zns,
passthru, pci-epf, rdma and configfs
- Various other fixes and cleanups
- MD updates via Yu Kuai:
- llbitmap reshape support, the large series wiring exact bitmap
mapping and reshape lifecycle through raid5 and raid10, growing
the page cache in place, and remapping checkpointed bits as
reshape progresses
- raid5 fixes for lockless max_nr_stripes and recovery_offset
accesses, a reshape deadlock with more failed devices than max
degraded, and bitmap batch counter consistency
- Atomic write handling for raid1/raid10, and removal of the
REQ_NOWAIT support from raid1/10/456
- raid5-ppl use-after-free fix in ppl_do_flush()
- A batch of smaller fixes across md core and the bitmap code
- s390/dasd ESE full-track write support and the surrounding
infrastructure, plus enabling CONTEXT_ANALYSIS for s390/block
- RWF_DONTCACHE support for block devices, built on new task-context
bio completion infrastructure, and wiring it up for the iomap and
buffer dropbehind writeback paths
- Async io_uring zone reset all, plus zone management command cleanups
allowing REQ_NOWAIT and tightening conventional zone rejection
- Block integrity refactoring: lift BIP_CHECK_FLAGS to the shared
header, handle nogenerate/noverify properly in fs-integrity, and drop
the blk-integrity.h include from bdev.c
- Split out a new blk_plug.h header
- ublk improvements: add UBLK_F_IO_DESC_SIZE, split request validation
from io_desc init, reject non-power-of-2 zone sizes in SET_PARAMS,
and a series of hardening fixes around map/unmap and auto buf reg
- null_blk cleanups and configfs serialization fixes
- nbd queue freeze removal on the setup paths, and a new
pre_defined_connections module parameter for pre-created devices
- blk-cgroup fixes for the race between policy activation and blkg
destruction, and accounting per-cpu stats over possible CPUs across
blk-stat, iolatency, iocost and kyber
- Various dio fixes: leak on metadata mapping error, validate user
space vectors during extraction, and set dma_alignment from the
backing file for loop and zloop direct I/O
- bio cleanups
- Various other fixes and cleanups all over
* tag 'for-7.3/block-20260819' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux: (241 commits)
nbd: add pre_defined_connections module parameter for pre-created devices
nbd: remove queue freeze for newly created nbd from netlink path
nbd: factor out a nbd_genl_foreach_sock
nbd: skip queue freeze when setting size at device startup
nbd: remove queue freeze in nbd_add_socket
nbd: clear queue limits on disconnect
nbd: disallow NBD_SET_SOCK on an active device
nbd: simplify find_fallback() by removing redundant logic
blk-mq: add missing call to srcu_barrier() in blk_mq_free_tag_set()
block: mtip32xx: synchronize ioctls with device removal
ublk: avoid teardown retry loop on xarray allocation failure
null_blk: fix UBSAN shift-out-of-bounds when zone_size is 0 or overflows
block: don't include blk-integrity.h in bdev.c
xfs: avoid double deferrals for RWF_DONTCACHE writes
loop: Fix recently introduced lock inversion
block: set QUEUE_FLAG_DYING unconditionally in blk_mark_disk_dead()
swim3: Add missing MODULE_DESCRIPTION
selftests: ublk: add SET_PARAMS validation test
selftests: ublk: add helper for SET_PARAMS
ublk: reject non-power-of-2 zone sizes in SET_PARAMS
...
|
||
|
|
c84d3e3130 |
Various ext4 updates for 7.3-rc1, including:
* Improve performance by allowing parallel DIO writes when we were
previously being overly conservative when checking whether it was safe
to avoid requiring an exclusive lock
* Improve the performance of ext4_mb_prefetch() used by fallocate() by
avoiding work when it is not needed
* Remove the unnecessary custom end_io function ext4_end_buffer_io_sync()
* Improve performance when performing an overwrite to an already uptodate folio
* Clean up how we handle deallocating EA inodes to avoid a potential
lock ordering issue when there is a failed mount while an EA inode is
still being evicted.
* Use str_plural() instead of a custom macro
* Avoid soft lockups or RCU stalls if there are many busy buffers
(caused by heavy I/O) while checkpointing
* Use scoped NOFS when starting a handle in nojournal mode
* Align fields in handle structure to optimize setting and getting
the h_type and h_line_no fields
* Fix documentation of the meta_bg block group layout
* Bug fixes, including
- Fix a potential out-of-bounds read in ext4_read_inline_dir()
- Fix a potential deadlock when concurrent xattr operations are racing
with each other when some of the xattrs are using the ea_inode feature.
- Fix a spurious warning with data=journal that can be triggered when
writeback races with remounting the file system read-only
- Fix a potential deadlock when EXT4_IOC_MIGRATE races with a file system
freeze operation
- Make sure all in-flight direct I/O operations are complete before
falling back to buffered I/O.
- Handle IOCB_NOWAIT properly when performing a extending DAX write
- Prevent potentially sleeping on a block allocation when
IOCB_NOWAIT is set
- Fix potential races when racing an inline data write with a page fault
- Propagate errors when adding or removing extent ranges
during a fast commit replay
- Avoid trying to expand an inode's extra size when it is being
evicted to avoid a number of corner case or deadlocks
- Avoid spurious error when retrying inode extra size expansion
- Fix corner cases where we underestimate the number of journal
credits needed
- Avoid hangs/crashes/WARNINGS caused by maliciously corrupted
file systems
- Don't issue spurious orphan clean message on RO file systems
- Avoid leaving the file system in an inconsistent state after a
crash when a WRITE_ZEROS in progress converting an unwritten
extent to a written extent
- Handle WRITE_ZEROS correctly when there are some partially dirtied
regions in the page cache
- Pass errors during zero-rage, truncate, or punch hole to the caller
if ext4_get_block() fails
- Wait for writeback to finish when triggered by zero-range or
zero-range for those devices that require stable writes
- If the reserved gid superblock field is set, set the reserved gid
instead of the reserved uid
-----BEGIN PGP SIGNATURE-----
iQEzBAABCAAdFiEEK2m5VNv+CHkogTfJ8vlZVpUNgaMFAmqD4ikACgkQ8vlZVpUN
gaO5wwf+I8AyUIsTJRUEHshfkcx+9TIEgIMy20haw641366rhP6h0dnkkypLjeVp
QyuO3Npivm7C9SO/IOX/ljhI7IBfoJtjfSpItBXRL/7TsSHYiqzxnCSNMWSwTBqP
wcfVqXHGZVMX2TIepqszrkp3sRFzsXTsT/pk5j78IVGgMAQ+T+LJP8EEB3SNEHuF
nTtXoHO8Rf0RZALE1oc1ywsZz6gvyBst5lTZxhAagRojNV15gPkns+oBkiQ6usUP
f8co5HXmscFOlqPvX1DK3oifKzXcD1DrQDJwIRULBnoj0Rhlx8zZbqm37uZ5ULoS
56G3YdMSziCzg7m0xlPMhWe68Eoabg==
=TbiH
-----END PGP SIGNATURE-----
Merge tag 'ext4_for_linus-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 updates from Ted Ts'o:
- Improve performance by allowing parallel DIO writes when we were
previously being overly conservative when checking whether it was
safe to avoid requiring an exclusive lock
- Improve the performance of ext4_mb_prefetch() used by fallocate() by
avoiding work when it is not needed
- Remove the unnecessary custom end_io function
ext4_end_buffer_io_sync()
- Improve performance when performing an overwrite to an already
uptodate folio
- Clean up how we handle deallocating EA inodes to avoid a potential
lock ordering issue when there is a failed mount while an EA inode is
still being evicted
- Use str_plural() instead of a custom macro
- Avoid soft lockups or RCU stalls if there are many busy buffers
(caused by heavy I/O) while checkpointing
- Use scoped NOFS when starting a handle in nojournal mode
- Align fields in handle structure to optimize setting and getting the
h_type and h_line_no fields
- Fix documentation of the meta_bg block group layout
- Bug fixes:
- Fix a potential out-of-bounds read in ext4_read_inline_dir()
- Fix a potential deadlock when concurrent xattr operations are
racing with each other when some of the xattrs are using the
ea_inode feature
- Fix a spurious warning with data=journal that can be triggered
when writeback races with remounting the file system read-only
- Fix a potential deadlock when EXT4_IOC_MIGRATE races with a file
system freeze operation
- Make sure all in-flight direct I/O operations are complete before
falling back to buffered I/O
- Handle IOCB_NOWAIT properly when performing a extending DAX write
- Prevent potentially sleeping on a block allocation when
IOCB_NOWAIT is set
- Fix potential races when racing an inline data write with a page
fault
- Propagate errors when adding or removing extent ranges during a
fast commit replay
- Avoid trying to expand an inode's extra size when it is being
evicted to avoid a number of corner case or deadlocks
- Avoid spurious error when retrying inode extra size expansion
- Fix corner cases where we underestimate the number of journal
credits needed
- Avoid hangs/crashes/WARNINGS caused by maliciously corrupted file
systems
- Don't issue spurious orphan clean message on RO file systems
- Avoid leaving the file system in an inconsistent state after a
crash when a WRITE_ZEROS in progress converting an unwritten
extent to a written extent
- Handle WRITE_ZEROS correctly when there are some partially dirtied
regions in the page cache
- Pass errors during zero-rage, truncate, or punch hole to the
caller if ext4_get_block() fails
- Wait for writeback to finish when triggered by zero-range or
zero-range for those devices that require stable writes
- If the reserved gid superblock field is set, set the reserved gid
instead of the reserved uid
* tag 'ext4_for_linus-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (56 commits)
ext4: fix estimate extent index blocks in ext4_ext_index_trans_blocks()
ext4: fix transaction overflow during writeback
ext4: teach ext4_meta_trans_blocks() about number of allocated extents
ext4: guard against NULL s_group_info in ext4_get_group_info
ext4: fix spurious message about orphan cleanup on RO fs
ext4: stop retrying saturated xattr cache entries
ext4: don't enable DAX on new encrypted files
ext4: protect WRITE_ZEROES written extents with orphan list
ext4: export converted block count from ext4_convert_unwritten_extents()
ext4: fix incorrect function call when initializing s_resgid
ext4: validate EA inode i_nlink in ext4_xattr_inode_iget
jbd2: align h_type and h_line_no in the handle structure on byte boundaries
ext4: enable scoped NOFS when starting a handle in nojournal mode
ext4: write back partial-zeroed edges in WRITE_ZEROES
ext4: zero out whole block for clean edges in WRITE_ZEROES
ext4: track partial-zero outcome per edge in ext4_zero_partial_blocks()
ext4: clarify return semantics of ext4_load_tail_bh()
ext4: move partial block zeroing earlier in ext4_zero_range()
ext4: check return value of ext4_get_block() in ext4_load_tail_bh()
ext4: skip tail block zeroing for inline data files
...
|
||
|
|
50c44fea13 |
for-7.3-tag
-----BEGIN PGP SIGNATURE-----
iQJPBAABCgA5FiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmqEFbYbFIAAAAAABAAO
bWFudTIsMi41KzEuMTIsMiwyAAoJEMVl1fnXbVg7/R0P/jNxH2bHnc3yNLTuSuIA
hj6QNSeTF6Q8bY5HGLbxIURr1npcODXGAFSZK5/vONZWgjSVy8j65gmciOPrD6Aq
YF9zjFY4JuRfltx2E1aOKLyeozq/LPPs/3VBcfTHv2vWiYEabkpvZrNu9Fu7iX7c
9TXSHzuBGp+Ao9faj9i0V/6en7hRxA6NW00FoIxvyANglJqcV35NV68zTuUeY62C
8pFoDpDMV2ePQZW9l4EUsgqsEL6/PF362HmVyWUREYtnfpqJuzTADMV5NH29jXN1
ZHw/P8La7gkHnzaJqDK1Nhs1L2vYLAdtIi5XdCMRCzHfuT2s7Wpo2VuXlpN77bP+
nR7ZMxbg6zAIvxAc246bYEUQ6LNxVTZ4+7gSDJXUbWdpM1zYoHYLPAvelsCvrpq+
2RJgChcEPNPHpQ4TXHLLERaJ6IvYFX1zfH+tU4yOGrapsF9wvVWpliR5dyJOGbj3
RDOmZdV1XHZzstb5muBgigC2Tqh/z4h2Inl3ShucxDpZUUAl7wXNAuogfUV88ioh
/zHqcSJVFYiSFi7m4Ml//TQgbtezUwFPHWdVoUybqHxAiBzC1HZ2/HBAyn93Cd8y
PbNYoF7D3bU7UQ7g+aJj9lbOm4ttamg00R3D3JGfYneufUOJWGAnditQv0xakORG
RXbq24AW0Im6O9zNU+E/iaCT
=rFrX
-----END PGP SIGNATURE-----
Merge tag 'for-7.3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs updates from David Sterba:
"This is the summer edition of btrfs changes, smaller than usual. Yet,
there are performance improvements in various areas or for specific
workloads and some notable changes like removing space cache v1 code
or mount option reduction.
User visible changes:
- free space v1 disabled by default; the v2 (free space tree) is mkfs
default since 5.15, filesystems with v1 still work but could be
slightly slower due to lack of block group caching
- mount option 'rescue=usebackuproot' requires read-only mount, it's
too risky to allow writable mount
- remove standalone mount option 'usebackuproot', deprecated in 5.9
- preserve constraints of NODATASUM and NODATACOW when chattr and
mount options may change the attributes
- remove arbitrary limitation of 4KiB for page size when allowing
block sizes smaller than page
- print messages when pinned block groups affect swap activation
Performance improvements:
- use iomap bounce buffer for direct io instead of a fall back to
buffered io; past correctness vs speed trade-offs dropped
performance to ~50% of theoretical maximum, now it's ~95%,
effectively doubled
- replace xarray with local LRU list for tracking inhibited
extent buffers, restored performance to pre-inhibition state
(relatively ~3x)
- remove unnecessary 1 jiffy delay in "non-SSD" mode with multiple
logging tasks, decrease latency, throughput increased ~5x on sample
workload
- skip hole detection during full fsync for files without holes
and lots of extents, reduce run time ~5x on sample workload
(microsecond ranges)
- reduce locking around extent readahead so it does not slow down
other tasks using an overlapping range
- enhance extent buffer allocation modes to allow NOWAIT semantics
in some cases
Notable fixes:
- write-protect folios during writeback, prevent concurrent mmap
and compress/checksumming/etc undesired interactions
- in zoned mode, handle transient overcommit full instead of going
read-only
- fix possible deadlock between defragmentation and delayed
allocation reservations
- handle remaining iputs at umount time
- fix lockdep warning between device scan locking and log mutex
- add workaround for degenerate RAID56 device count modes (2 and 3)
not supported by the parity calculation library
- restore check that subvolume is not read-only when changing ACLs
- retry reading verity data colliding with up-to-date status changes
Core:
- simplify raid56 stripe handling by using contiguous virtual
allocations
- in zoned mode, fix various metadata write issues in writeback or
unmount
- space reservation fixes
- remove unused data structure members
- more auto-freeing conversions
- error pointer values are printed using %pe format"
* tag 'for-7.3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: (72 commits)
btrfs: skip hole detection during full fsync for files without holes
btrfs: add extra ASSERT()s to make sure the folio size is correct
btrfs: use GFP_NOWAIT for tree block readahead
btrfs: enable unlocked NOFAIL retry for eb allocations
btrfs: add struct btrfs_eb_prealloc
btrfs: factor init_extent_buffer from __alloc_extent_buffer
btrfs: qgroup: fix a wrong length calculation in qgroup_free_reserved_data()
btrfs: add validation for extent states
btrfs: use aligned range for locking in reflink
btrfs: use aligned range for locking in extent_fiemap()
btrfs: zoned: don't clobber the extent buffer when zeroing it out
btrfs: zoned: drop stranded dirty metadata buffers at unmount
btrfs: zoned: drop stranded dirty metadata on transaction abort
btrfs: zoned: flush active metadata block group at btree_writepages() start
btrfs: convert reflink.c to use btrfs_inode as parameters
btrfs: use simple booleans for log_commit field in struct btrfs_root
btrfs: check for exit condition after waking in wait_log_commit()
btrfs: move condition for log commit wait into wait_log_commit()
btrfs: remove log batch counter use for fsync
btrfs: stop sleeping for one jiffy in non-ssd mounts during log commit
...
|
||
|
|
9328b3b03b |
\n
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEq1nRK9aeMoq1VSgcnJ2qBz9kQNkFAmqFw00ACgkQnJ2qBz9k QNlJlgf/SylCykcdsaqBVJd9hTrg0L6AdMKyc/PpdvyjK7qWOrXLzQFV9p7BHrER pGixy+k/5QTlWRAQ7X7okHI9uo6cMzxP/OeLqiXszBPlinRxsELb1GH89+5jOrQh oAcDci0LxX9dyBXcnl+MFgS6FPURQRnGqCeyMc+EnqHF8LYTjy05jWw/sn8Ok6WF vTBV1gl1YLN6bA+cRDVH3BBWf9irzDvnbBTUo6CRF0H5wPxiuy/ddgaYxgd8GDD/ jKsZ/hmL90695CGmvoGC3WtMpAUJm/rLX6aqoYltwQYbKhVJpfAh58IhJGpgsRG4 l4kVxtZvjvP5jMskXm5SbCMAzB8Fzg== =vznt -----END PGP SIGNATURE----- Merge tag 'fs_for_v7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs Pull ext2, udf, isofs, and quota updates from Jan Kara: - Remove deprecated quota code printing warnings about exceeded quota directly to console - Various udf & isofs hardening for handling of corrupted filesystems - Fix a possible data loss in udf when converting files from inline to out-of-line format - Simplify EIO error handling in ext2 xattr code * tag 'fs_for_v7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: udf: Fix data loss when converting inline inodes to out of line udf: Move udf_map_block() up ext2: Simplify error handling of IO error when adding xattr isofs: Drop support of directory entries straddling blocks isofs: validate directory records consistently quota: remove CONFIG_PRINT_QUOTA_WARNING code udf: Fix i_lenExtents truncation on 32-bit kernels isofs: release zisofs block pointer buffer head udf: Fix bh leak for unallocated space entries udf: bound lengthAllocDescs from unallocated space entry UDF symlink pathComponent header OOB read isofs: fix out-of-bounds page array access on empty zisofs block udf: reject VAT indexes equal to the entry count udf: Mark LVID buffer as uptodate before marking it dirty udf: avoid recursive s_alloc_mutex deadlock when freeing AED blocks udf: validate extent partition references in udf_current_aext() |
||
|
|
81e51378b7 |
\n
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEq1nRK9aeMoq1VSgcnJ2qBz9kQNkFAmqFwEgACgkQnJ2qBz9k QNnNvAgAxVRKKfkAkxzx1iRCFtRRXSeWMfUeT7hF5hHyGUN+ZrVomAFYBNXXqFPA fdpG9OLadQXmReqv6gtOOrV2cls92BU3KO01U7yXHEZmE/zDlEGSXNpK1elsponY nx8Ukiz911R5Be0JB/x/tUWW1bDi4HEO2eLfwY9MUuzNDuIvKAkhSO8ZP2teKChR ZFl/ctiiblLOsmL3rhQeJWzjG06fjEdD0b1ZbpQtjjc2bmIWRV0MQxXs/wvkt1Mz 0an1PAp3L478tGJAGQKD5TArTitpmxmGPmj6jw8WQXMvYOfkoyyeeboybx24JG0i QIMMVEcPzZwtLVTX4UbOnnUU5JpUqQ== =PDAd -----END PGP SIGNATURE----- Merge tag 'fsnotify_for_v7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs Pull fsnotify updates from Jan Kara: "A couple of assorted fixes (mostly stuff spotted by Sashiko) for fsnotify subsystem. I'm also removing Matt as a reviewer because he was not active in fsnotify in last years and after he stopped working for Google I don't have a working contact to him" * tag 'fsnotify_for_v7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: fsnotify: Fix stale object mask after concurrent mark updates fanotify: report full event length for FIONREAD fanotify: fix use-after-free of file range info fanotify: stop permission watchdog when timeout is zero fsnotify: Remove Matt Bobrowski as a reviewer fanotify: initialize permission event watchdog state |
||
|
|
d141ec2825 |
NFSD 7.3 Release Notes
Jeff Layton contributed CB_NOTIFY support to NFSD's NFSv4.1
directory delegations. The server used to recall a delegation as
soon as the directory changed. NFSD now watches delegated
directories through fsnotify and reports adds, removes, renames,
and directory attribute changes, carrying the filehandle and
attributes of the affected entry, so clients can keep their
caches. Some of the NOTIFY4 flags come from RFC 8881bis.
Jeff Layton also continued the netlink work that started in v7.2.
A new server-stats-get operation reports what /proc/net/rpc/nfsd
publishes, plus NFSv4 callback counts, and SUNRPC now keeps its
per-procedure call counts per network namespace, so a container
sees its own numbers. nfsstat reads all of this over netlink, with
a procfs fallback for older kernels.
SUNRPC's service thread pool mode selection is gone. Pernode is
the right choice on any host we run today, so the auto, global,
and percpu modes have been removed. A single-node host still gets
one pool. A multi-NUMA host now gets a pool per node.
sunrpc.pool_mode accepts the old names but no longer selects
anything.
The rest is bug fixes, clean-ups, and small optimizations: an
async COPY offload rework from Jeff Layton, more use-after-free
fixes in the NFSv4 state revocation paths, percpu counter
contention removed from the reply cache and IO accounting, and a
long list of hardening fixes from Chris Mason. Sincere thanks to
all contributors, reviewers, testers, and bug reporters who
participated in the v7.3 NFSD development cycle.
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEKLLlsBKG3yQ88j7+M2qzM29mf5cFAmqDDs4ACgkQM2qzM29m
f5eUTQ/+NgtZZ93ssYPbu5vW1lnxI0zVMPwBw+jvdF4YShaLUTVD3AYN/wOn2n2v
Y0ULB2QOyz5zXq+9e9sL/zWJNPsGucx4G4pfcXzn96e3zPkZPChaJUKRQd347kPc
gkaExMxQBwqU7xDIaBF+g1vh4pogORfhc4xi0zE0j4kqiYJOQCJIUg33SNLrqeSa
DG7IbTuS+nvFBalbUQiWaL7DMxO2N2JlYbpU15kzBuJ8GLK7I3kPPTDGKEbEaUuF
m8krI6Drdrwb1puiZnjUO+OHvalC5JzKcLkHG9Ps1KlUgfYDZ546waPIcpCT0KjM
JFG3Avg2Zu9o+cz1AZB9Kq7epPQgHzNea3h48DOLvJP9r97cvObkg2ZocMzlHe0/
yy2qRCBpX41MWDgckB6hCVP1l/l0u7EatpXxMtdBm4Jnv6a6Em39RLX4MzFVcJ5t
cYROdLEAfwblIeJyOJm197LjjhKb7minPWRWaYwnGMe05VXUXSh7MZI/Rw7NkJev
P8p+bt1CEv1pEM0ArrDmcjPvsX2JJXMsspHovf/ymbTYLdDf9I/7NFLE/Jc6c9BT
h9/oMBcw7lumlB5aq3L/NOlXQmjtoGTQVjyMrKDwtRQXjQgFo8gaB5nXSIlB4ik+
DFz2ajp+F07VATS89Dc2m7ALO08pdNwzn4p8jq/IKnqlGWlxNIE=
=g1IS
-----END PGP SIGNATURE-----
Merge tag 'nfsd-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
Pull nfsd updates from Chuck Lever:
- CB_NOTIFY support for NFSD's NFSv4.1 directory delegations
The server used to recall a delegation as soon as the directory
changed. NFSD now watches delegated directories through fsnotify and
reports adds, removes, renames, and directory attribute changes,
carrying the filehandle and attributes of the affected entry, so
clients can keep their caches. Some of the NOTIFY4 flags come from
RFC 8881bis (Jeff Layton)
- Continued netlink work
A new server-stats-get operation reports what /proc/net/rpc/nfsd
publishes, plus NFSv4 callback counts, and SUNRPC now keeps its
per-procedure call counts per network namespace, so a container sees
its own numbers. nfsstat reads all of this over netlink, with a
procfs fallback for older kernels (Jeff Layton)
- Remove SUNRPC service thread pool mode selection
Per node is the right choice on any host we run today, so the auto,
global, and percpu modes have been removed. A single-node host still
gets one pool. A multi-NUMA host now gets a pool per node.
sunrpc.pool_mode accepts the old names but no longer selects
anything.
- Bug fixes, clean-ups, and small optimizations:
- async COPY offload rework (Jeff Layton)
- more use-after-free fixes in the NFSv4 state revocation paths
- percpu counter contention removed from the reply cache and IO
accounting
- a long list of hardening fixes (Chris Mason)
Sincere thanks to all contributors, reviewers, testers, and bug
reporters who participated in the v7.3 NFSD development cycle.
* tag 'nfsd-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: (182 commits)
nfsd: export NFSv4 callback op stats via netlink
nfsd: count NFSv4 callback operations per netns
sunrpc: remove unused svc_version vs_count field
nfsd: implement server-stats-get netlink handler
sunrpc: use per-net counts in svc_seq_show()
sunrpc: add per-netns per-procedure call counts to svc_stat
NFSD: Document reply_cache_stats ABI
NFSD: Eliminate percpu counter contention in IO byte accounting
NFSD: Eliminate percpu counter contention in reply cache statistics
NFSD: Eliminate percpu counter contention in DRC memory accounting
NFSD: Fix off-by-one in DRC bucket pruning limit
NFSD: Relocate NFSv4 "supported attributes" to new header
NFSD: Relocate nfsd4_set_netaddr()
NFSD: Relocate nfsd_user_namespace()
NFSD: Move struct readdir_cd
NFSD: Move the export.h include from nfsd.h to auth.c
NFSD: Remove '#include "nfsd.h"' from fs/nfsd/cache.h
NFSD: include "netns.h"
NFSD: Explicitly include "stats.h"
NFSD: Make "stats.h" self-contained
...
|
||
|
|
ada9ccfb81 |
Fixes:
orangefs: fix double-free of trailer_buf orangefs: skip leading spaces before parsing client debug masks Cleanup: orangefs: Remove commented out code New: orangefs: use folio_pos() and folio_size() in orangefs_page_mkwrite() -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEWLOQAZkv9m2xtUCf/Vh1C1u0YnAFAmqEfo8ACgkQ/Vh1C1u0 YnCw7g/6A8tslelLuzkjMtF91rNpSQZtluVqT84CclmxFCChFlUI/M7fLgvnntph 8EQ70clSfiKsTgqnB0P0PQrIyxgY/fVgOFFGT6SBrl2iHr9rqF7nkv1GH5Ymn/W6 WhMmYKPiES0yZyNOchOBr35v7BG5m26FJfGzBCTxmTwo5SeqBziaGcR5lBT9pIoB z89Aa+x6BI3GOG3d8bOCnmiDJqypyaVzUqBIccJaWVUkxT9svZo51hHweaM/GF9w XC8DYrkR7bOb4IV+GU2vLKFn1r4PAMq720aVRtvWWm+LOpszhVCxafu4w/kqbaWl 1T8UHoAEGVSN8I3EJSc2gbZ7ZjoY6WCSOBSlN9I7xWy4HRt1zZ+FBPp5UGvhlcyU jznhhufik6dvBdHLd78yJBcrQRYfD35aWRIlPnJs4Z72AYX3+oLL2wvyM0SNd0aF IQ35GheSdlpUsYHZHZyFaK3Iw68VcOoYtCl+7DQhrhFwHz9NvDXgSW3wJI064yBU wf/Y4xAxy13A6o8FLzOk6jBZJ3OpaqcKO9liIXiq0yZ/uLikhXv096Ags4XArJh+ oS21vd1gUqN2xCaFJcrSktjmVkCdXLHo94HKZ6A+jx82xyByeprJMmPJPP9EBt3Y cUgFSfraAh2dZ+zxVZ/my5qrPo/7hP4IXo35fyMiR41m14wsgkI= =n1xT -----END PGP SIGNATURE----- Merge tag 'for-linus-7.3-ofs1' of git://git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux Pull orangefs updates from Mike Marshall: "Fixes: - fix double-free of trailer_buf - skip leading spaces before parsing client debug masks Cleanup: - Remove commented out code New: - use folio_pos() and folio_size() in orangefs_page_mkwrite()" * tag 'for-linus-7.3-ofs1' of git://git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux: orangefs: skip leading spaces before parsing client debug masks orangefs: Remove commented out code in find_cached_xattr orangefs: use folio_pos() and folio_size() in orangefs_page_mkwrite() orangefs: fix double-free of trailer_buf on readdir copy failure |
||
|
|
dc83d18cdd |
Changes for 7.3-rc1
Added:
load ATTR_BITMAP run extents from $MFT extension records
initialize err in attr_wof_frame_info
reserve NUL byte when converting UTF-16 names
reject restart table growth beyond U16_MAX entries
validate dirty page table on log replay
basic support for alternative data streams
validate ef->size covers the record's name and value
Fixed:
slab-out-of-bounds write in ni_create_attr_list()
out-of-bounds read of INDEX_ROOT in reparse/objid init
boundary check in ntfs_dir_count()
info-leak in ntfs_rename()
lseek EINVAL on sparse/compressed files with 64-bit clusters
info-leak on partial LZNT decompress in ni_read_frame()
bound page_lcns[] index by the log record
memory leak in indx_find_sort()
integer overflow in MFT cluster validation
reject out-of-range evcn in mi_enum_attr()
out-of-bounds read in read_log_rec_buf()
Changed:
widen inode/record number storage to u64
cosmetic fixes and improvements
rename 'err' to 'ret' in read paths
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEh0DEKNP0I9IjwfWEqbAzH4MkB7YFAmqES2UACgkQqbAzH4Mk
B7Y4QhAAjojTH+HLSlwam+kWHgABEGLn4Ka0/1zMM/3pcct8L/fdVRg3NbnU5VmA
j7Ru76kQxWVAxkGm4Vxbsed62w0/7n5Y25pwCez0x0xKYCP6fEmT8r+R7dwCe9zb
o66g4ZSrMOb0YYaQKiEa24SwU+3vHO1K/WIYt7ay678BN/6Xj6DpY4L1mLpD8gEP
vEWW7vaMiwr27u4MY0r7OW3sj5S3SBxAOhCfhFSeV63egS4Ropenohdj5Lpmrp8N
GZd7NtVD7R1sZiswAGrbqXYWeohUxAMrttLo8sqOBP9wNUu2Cyhde3DlHz1pmU3L
zsairS9LmZNS5ZjdKFt3l/zcLOszBdfiEJKauFbU1g47pB8XHcLHWcZiNLcBhwlR
P4DJHdKXYnK1yixoONKiwnyXr4ApQhnevrfysrICYv6NNCo9KtvLBAUscaweYDmn
SaGvAO57IZrwy54N37IOS9aEjXdANcYvvcJo6HKAsdPENT4sfTfBPvWxTuIqy4i6
lvGJgzH/3LGrf1M9jjqw1zT7LYyKBNhp+2AX1TNUs4wxkO3mDSAFxqTPSjZNK1A9
sgT0+QmCYNpssJr1QUPlfDPE76DwAOYGMAfudGoG1bVauNBPvXMx3Mnqnynmw53t
yS90PGzuoRq5M2/tEwrF/uELsHWHF9zgMqSNdnlq2JmRXsnwTEE=
=foIo
-----END PGP SIGNATURE-----
Merge tag 'ntfs3_for_7.3' of https://github.com/Paragon-Software-Group/linux-ntfs3
Pull ntfs3 updates from Konstantin Komarov:
"Added:
load ATTR_BITMAP run extents from $MFT extension records
initialize err in attr_wof_frame_info
reserve NUL byte when converting UTF-16 names
reject restart table growth beyond U16_MAX entries
validate dirty page table on log replay
basic support for alternative data streams
validate ef->size covers the record's name and value
Fixed:
slab-out-of-bounds write in ni_create_attr_list()
out-of-bounds read of INDEX_ROOT in reparse/objid init
boundary check in ntfs_dir_count()
info-leak in ntfs_rename()
lseek EINVAL on sparse/compressed files with 64-bit clusters
info-leak on partial LZNT decompress in ni_read_frame()
bound page_lcns[] index by the log record
memory leak in indx_find_sort()
integer overflow in MFT cluster validation
reject out-of-range evcn in mi_enum_attr()
out-of-bounds read in read_log_rec_buf()
Changed;
widen inode/record number storage to u64
cosmetic fixes and improvements
rename 'err' to 'ret' in read paths"
* tag 'ntfs3_for_7.3' of https://github.com/Paragon-Software-Group/linux-ntfs3: (21 commits)
fs/ntfs3: validate ef->size covers the record's name and value
fs/ntfs3: fix out-of-bounds read in read_log_rec_buf()
fs/ntfs3: reject out-of-range evcn in mi_enum_attr()
fs/ntfs3: fix integer overflow in MFT cluster validation
fs/ntfs3: Add basic support for alternative data streams
fs/ntfs3: Rename 'err' to 'ret' in read paths
fs/ntfs3: Fix memory leak in indx_find_sort()
fs/ntfs3: bound page_lcns[] index by the log record
fs/ntfs3: validate dirty page table on log replay
fs/ntfs3: reject restart table growth beyond U16_MAX entries
fs/ntfs3: fix info-leak on partial LZNT decompress in ni_read_frame()
fs/ntfs3: reserve NUL byte when converting UTF-16 names
ntfs3: initialize err in attr_wof_frame_info
fs/ntfs3: fix lseek EINVAL on sparse/compressed files with 64-bit clusters
fs/ntfs3: load ATTR_BITMAP run extents from $MFT extension records
ntfs3: fix info-leak in ntfs_rename()
ntfs3: fix boundary check in ntfs_dir_count()
fs/ntfs3: fix out-of-bounds read of INDEX_ROOT in reparse/objid init
fs/ntfs3: fix slab-out-of-bounds write in ni_create_attr_list()
fs/ntfs3: cosmetic fixes and improvements
...
|
||
|
|
8f421dfec2 |
Changes since last update:
- Allow source fds via fsconfig(), in addition to source paths - Use dedicated metadata inodes for file-backed mounts - Disallow invalid interlaced ztailpacking pclusters - Validate on-disk compression algorithm IDs against supported ones - Fix unused pcluster pools on higher page-size platforms -----BEGIN PGP SIGNATURE----- iQJFBAABCgAvFiEEQ0A6bDUS9Y+83NPFUXZn5Zlu5qoFAmqD0icRHHhpYW5nQGtl cm5lbC5vcmcACgkQUXZn5Zlu5qryQA/+L588+cfcFeLOEdugWWAwxIMcC6UZQza3 /XQD+jzlBbK/d1TQs3H9rdIibo9+5WVOG9cME4oS195Q+Di29/BmEfqYCvjwXZDr mUrl68TdsPw7fI2vCpLRduCJPXpURqJYBX77G2NfWcfFNNjZykNBOe9OAHgbBqwI 7+UmhxvRB2TvZidZ2OhCXC02dcSBcHifscniLbC9XFdhKKRgEC5Zk8jrJ+YoSIfF R7aa8zrAe1I7AI09aRPKTwjiDCueBvqE72tKodXtYr+Ay0TPWEzVZpFMPW3fjGzb TDAWPfA5oK7U7L+euGaILFXOrBnfyfc+iH1P4t6jsbFVZTemvVKv/mO/Rk3vUj+l riwDH/ZPrQguPjpMuQrXCEtFd+zEfhSpXVMYNU1MBgiPnB/Puts6C89UYtyueYf8 9nNSrKsdeZnxiimx/VnYvBNz+8l7tonvcykDLZkM7tJ6PhjyO64GzivRwN0QqctU JygsXTEBbVPHf6degKpxbx2J2FyH+Nr3tBcq/eIQqI2wENwr+qUyfQ4zmlPpQCoS fAIHqdmo2TMZYNcLT5sG1+xScETiTPvSWXsBr4iPpqWCA/QiY7rhbkTN+A0DNMcw utw9LydnlV6ERt0s56e+jmyNdgf5idkxDN/7uzvregIVCxlVCZpluNny3MBgpTPN RqhyM+v00Jk= =jqEn -----END PGP SIGNATURE----- Merge tag 'erofs-for-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs Pull erofs updates from Gao Xiang: "The most notable enhancement is to allow passing source fds via fsconfig() for composefs. The others are all various fixes: - Allow source fds via fsconfig(), in addition to source paths - Use dedicated metadata inodes for file-backed mounts - Disallow invalid interlaced ztailpacking pclusters - Validate on-disk compression algorithm IDs against supported ones - Fix unused pcluster pools on higher page-size platforms" * tag 'erofs-for-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs: erofs: fix unused pcluster_pools for higher page sizes erofs: guard on-disk algorithm IDs against Z_EROFS_COMPRESSION_MAX erofs: fix interlaced ztailpacking pclusters erofs: use dedicated meta inodes for file-backed mounts erofs: accept source file descriptor via fsconfig erofs: fix typo in error messages |
||
|
|
62abb6cffd |
NVDIMM and DAX for v7.3
Documentation cleanup: nvdimm-btt: clean up kernel-doc warnings libnvdimm: nd.h: clean up kernel-doc warnings DAX prepare for FAMFS: dax: fsdev.c minor formatting cleanup dax: fix holder_ops race in fs_put_dax() dax: read holder_ops once in dax_holder_notify_failure() dax/fsdev: fail probe on invalid pgmap offset dax/fsdev: use __va(phys) for kaddr in direct_access dax/fsdev: clear pgmap ops and owner on unbind dax/fsdev: don't leave a dangling dev_dax->pgmap on probe failure dax/fsdev: clear vmemmap_shift when binding static pgmap dax/fsdev: fix multi-range offset in memory_failure handler dax: fix misleading comment about share/index union in dax_folio_reset_order() NVDIMM misc fixups: nvdimm/btt: reject an arena whose nfree is below the lane count libnvdimm/labels: Bound the on-media label size before the shift libnvdimm/labels: Prevent integer overflow in __nd_label_validate() Coccinelle reported cleanups: nvdimm: ndtest: remove redundant NULL check before vfree() nvdimm: nfit: remove redundant NULL check before vfree() -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQR/ATNjDEocsE1wudD5tRoRP7nxxwUCaoOJMQAKCRD5tRoRP7nx x6FQAQCmAfXFZK5eE+nujrFanI5d2iiKcTefwR/LYu0HOVG82AEA/c39OZz4jhSj bx49jE45o7qTaZHzY8ADSBVl8GHSOQA= =0lJA -----END PGP SIGNATURE----- Merge tag 'libnvdimm-for-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm Pull NVDIMM and DAX updates from Alison Schofield: "Most are DAX preparatory patches for FAMFS support, along with a few NVDIMM fixes and documentation cleanups. - Documentation cleanup, removing kernel-doc warnings - preparing DAX for FAMFS - misc NVDIMM fixups with cleanups for issues reported by Coccinelle" * tag 'libnvdimm-for-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: nvdimm-btt: clean up kernel-doc warnings libnvdimm: nd.h: clean up kernel-doc warnings dax: fsdev.c minor formatting cleanup dax: fix holder_ops race in fs_put_dax() dax: read holder_ops once in dax_holder_notify_failure() dax/fsdev: fail probe on invalid pgmap offset dax/fsdev: use __va(phys) for kaddr in direct_access dax/fsdev: clear pgmap ops and owner on unbind dax/fsdev: don't leave a dangling dev_dax->pgmap on probe failure dax/fsdev: clear vmemmap_shift when binding static pgmap dax/fsdev: fix multi-range offset in memory_failure handler dax: fix misleading comment about share/index union in dax_folio_reset_order() nvdimm/btt: reject an arena whose nfree is below the lane count libnvdimm/labels: Bound the on-media label size before the shift libnvdimm/labels: Prevent integer overflow in __nd_label_validate() nvdimm: ndtest: remove redundant NULL check before vfree() nvdimm: nfit: remove redundant NULL check before vfree() |
||
|
|
9d2ed026f0 |
Summary
* Documentation
Fix kernel-doc warnings by adjusting in file documentation.
* Consolidate do_proc_* function into do_proc_vec.
Consolidate three slightly different implementations of applying a converter
on all elements of a vector. Fixes to this function now propagate to the three
types.
* Miscellaneous
Replaced CONFIG_PROC_SYSCTL with CONFIG_SYSCTL (they were the same) and
restrict cad_pid modifications to global root (GLOBAL_ROOT_UID)
* Testing
This series was run through sysctl selftests/kunit test suite in x86_64. And
went into linux-next around rc2, giving it a bit more than a month of testing.
-----BEGIN PGP SIGNATURE-----
iQGzBAABCgAdFiEErkcJVyXmMSXOyyeQupfNUreWQU8FAmp0ga8ACgkQupfNUreW
QU9RZQv/UFBopK15/HcUPWAp8h0Yq68Reij0ryPhuOuoqRaWjLrz5iT9SvNW4IZH
WfAHal9+gVyAov2TvZUDHE0iojYa1S7l1MSBSvzlEijZnbglnt+63Ijfria3FTr2
FIqk7gOxCpDg7kRh1GkIm8yc6Ke7T2IcbMT8XW5PAs43QqMPgGfeUry14sr6H89u
pc1vXS/PcRDdsKkYKADCuljGG3ywL/7frDhSRcc+5WkCACOujzosmXTL10TVVs7H
6Lz3vujtQyCnv3UxlHicsJQXD60m2gqbCLcqa5gndfE5jO2nS3ZTqRBALT9Cimuk
43k+cKgJwOa5ry9OFXmp+in57hgOg8AZqWWENY2W0RaU6Tw7Ui5x6z36ZtE5PR9u
NlNAOprv6UnKOQ6Bc4GGtfSMh+EviqQBSNQroEz4UxLdrFx2X7SxkSgz5I6gLbzf
w+KZpQ3Y3Kjvr9ywkQUftekWqaeapv/OfrjGXRwiIBYhlurmKqvFpjjSQXmjow9u
RD1bfR9X
=aYrQ
-----END PGP SIGNATURE-----
Merge tag 'sysctl-7.03-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/sysctl/sysctl
Pull sysctl updates from Joel Granados:
- Fix kernel-doc warnings by adjusting in file documentation
- Consolidate do_proc_* function into do_proc_vec
Consolidate three slightly different implementations of applying a
converter on all elements of a vector. Fixes to this function now
propagate to the three types.
- Replace CONFIG_PROC_SYSCTL with CONFIG_SYSCTL (they were the same)
and restrict cad_pid modifications to global root (GLOBAL_ROOT_UID)
* tag 'sysctl-7.03-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/sysctl/sysctl:
sysctl: remove CONFIG_PROC_SYSCTL, it just mirrors CONFIG_SYSCTL
sysctl: move the "cad_pid" entry from pid_table[] to kern_reboot_table[]
sysctl: repair some kernel-doc comments
sysctl: add Returns: kernel-doc for all functions
sysctl: Update API function documentation
sysctl: Rename proc_doulongvec_minmax_conv to proc_doulongvec_conv
sysctl: Group proc_handler declarations and document
sysctl: Replace do_proc_do{int,ulong,uint}vec with do_proc_vec
sysctl: Add negp parameter to douintvec converter functions
sysctl: Move default converter assignment out of do_proc_dointvec
|
||
|
|
c5e640fe34 |
smb: server: remove unused DES crypto header
The DES crypto header is no longer used after the removal of NTLMv1
authentication. Remove it now that the server no longer selects
CRYPTO_LIB_DES.
Fixes:
|
||
|
|
ed91d80242 |
smb: server: Remove obsolete "select CRYPTO_LIB_DES" from Kconfig file
The DES encryption in the smb server code has been removed in 2021
with the removal of the insecure NTLMv1 authentication code. Thus
we don't need this "select" statement here anymore.
Fixes:
|
||
|
|
80b6367ec3 |
ksmbd: keep TCP timers alive for kernel sockets
ksmbd creates its listening socket with sock_create_kern(). Kernel sockets do not hold a network namespace reference by default. Accepted sockets inherit this state. When an accepted socket is released, tcp_close() clears its pending TCP timers for a kernel socket after the socket enters an orphaned state. If the peer is unreachable while ksmbd sends a FIN, this can leave a FIN-WAIT-1 orphan without a retransmission timer. Upgrade the listening socket's network namespace reference before kernel_listen(). Accepted sockets inherit the reference, so the TCP stack can keep the retransmission timer active and apply its normal orphan retry policy. Preserve the existing graceful shutdown behavior. Link: https://github.com/openwrt/openwrt/issues/24744 Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
56549c18a4 |
ksmbd: enable TCP keepalive for accepted connections
A client that disappears without sending a FIN or RST can leave its ksmbd connection in ESTABLISHED indefinitely. ksmbd sets a socket receive timeout, but the connection receive loop retries timeout errors without a limit, so the connection remains in conn_list and consumes the per-IP connection quota. Enable SO_KEEPALIVE on accepted TCP sockets so the TCP stack can detect a silent peer failure. The keepalive idle time, interval, and probe count remain controlled by the existing TCP sysctl settings. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
b2326338dc |
efivarfs: Rate limit statfs() handler
Ravi reports that statfs() may be called by unprivileged users on the
efivarfs mount point, which may result in a flood of calls to the
QueryVariableInfo() runtime service. These calls are disproportionately
costly on x86 systems where the variable store is backed by SMM, as each
SMM entry requires a rendez-vous of all the CPUs.
So rate limit the calls to QueryVariableInfo() at twice per second, and
return the most recently obtained value for calls that are elided.
Cc: <stable@vger.kernel.org>
Reported-by: Ravi Bangoria <ravi.bangoria@amd.com>
Fixes:
|
||
|
|
766062a82e |
ntfs: reject invalid empty mapping pairs
Reject an attribute with empty mapping pairs if it has inconsistent
highest VCN and size.
Fixes:
|
||
|
|
9969d58a9b |
ntfs: fix resource leak in ntfs_new_attr_flags
When handling resident attributes that don't need sparse/compressed
changes, ntfs_new_attr_flags() returns 0 directly at line 678 without
calling unmap_mft_record() or ntfs_attr_put_search_ctx(). This leaks
the MFT record mapping and attribute search context.
An unprivileged user can cause a denial of service by repeatedly
calling setxattr(2) with system.ntfs_attrib on files with resident
attributes, eventually exhausting kernel memory.
Fix by replacing the direct return with goto err_out to ensure proper
cleanup of resources via the existing cleanup code.
Fixes: e791930240a5 ("ntfs: fix resident conversion in ntfs_new_attr_flags")
Cc: stable@vger.kernel.org
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
|
||
|
|
8168434096 |
ntfs: validate usa_ofs before preserving the update sequence number
When ntfs_mft_record_alloc() reuses a free mft record it reads the old
update sequence number straight from the on-disk record:
usn = *(__le16 *)((u8 *)m + le16_to_cpu(m->usa_ofs));
Here m points into the raw $MFT page-cache folio, which still holds
unvalidated, MST-protected bytes: the folio is read by a plain
iomap_read_folio() and neither post_read_mst_fixup() nor
ntfs_mft_record_check() has run on it (both work on private copies).
m->usa_ofs is therefore an untrusted u16, and a corrupted record can put
it past the end of the record so the two-byte read lands outside the
folio. Reading such a record while creating a file gives, under KASAN:
BUG: KASAN: use-after-free in ntfs_mft_record_alloc+...
Read of size 2 at addr ...
ntfs_mft_record_alloc -> __ntfs_create -> ntfs_create -> path_openat
Only preserve the old update sequence number when usa_ofs is even and in
range, mirroring the check ntfs_mft_record_check() already applies;
otherwise leave usn zero, which the existing restore below skips.
Fixes:
|
||
|
|
98716c9fce |
ntfs: fix off-by-one page overflow in ntfs_decompress()
The per-token range check in ntfs_decompress() uses
if (cb >= cb_sb_end || dp_addr > dp_sb_end)
break;
so dp_addr == dp_sb_end falls through to the symbol copy
`*dp_addr++ = *cb++`, writing one byte past the destination page. Since
NTFS_SB_SIZE == PAGE_SIZE the destination is a single page, so the byte
lands in the adjacent page, and *dest_ofs is left one past the sub-block
end (the later `*dest_ofs &= ~PAGE_MASK` then yields 1, not 0, so the page
is never finalized and later sub-blocks keep writing further past it). A
corrupted compressed $DATA attribute thus produces a bounded run of
out-of-bounds writes when the file is read.
Break as soon as dp_addr reaches dp_sb_end; a full sub-block still
completes, as its final copy advances dp_addr to exactly dp_sb_end.
Fixes:
|
||
|
|
763c097f71 |
ocfs2: bound-check dir entries in the inline-data re-validation scan
ocfs2_dir_foreach_blk_id() re-scans the inline data area the same way
ocfs2_dir_foreach_blk_el() re-scans a directory block, and is missing the
same two bounds:
for (i = 0; i < i_size_read(inode) && i < offset; ) {
de = (struct ocfs2_dir_entry *)(data->id_data + i);
if (le16_to_cpu(de->rec_len) < OCFS2_DIR_REC_LEN(1))
break;
i += le16_to_cpu(de->rec_len);
}
ocfs2_validate_inode_block() keeps i_size inside the inline area:
if (le16_to_cpu(data->id_count) >
ocfs2_max_inline_data_with_xattr(sb, di))
if (le64_to_cpu(di->i_size) > le16_to_cpu(data->id_count))
and that area runs to the end of the inode block, so for a full inline
directory data->id_data + i_size is the end of di_bh->b_data. A bogus
rec_len leaves i in the last OCFS2_DIR_REC_LEN(1) - 1 bytes of it, and
de->rec_len, at byte offset 8 within the entry, is then read past the
block.
The emit loop below hands i_size_read(inode) to ocfs2_check_dir_entry(),
which refuses both an entry that close to the end and one whose rec_len
runs past it. Apply the same two bounds to the re-validation scan,
reading i_size once into a local as ocfs2_check_dir_entry() takes it as
@size.
Unlike the extent case there is no mask to corrupt here: an unbounded i
only sets ctx->pos past i_size, which ends the readdir early rather than
moving it to the wrong place.
Link: https://lore.kernel.org/20260811024337.3972976-3-zhanxusheng@xiaomi.com
Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Heming Zhao <heming.zhao@suse.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||
|
|
bec0eed29b |
ocfs2: bound-check dir entries in the readdir re-validation scan
Patch series "ocfs2: bound-check both readdir re-validation scans", v2.
This patch (of 2):
When the inode version changed since the last readdir(),
ocfs2_dir_foreach_blk_el() re-scans the directory block from its start to
relocate the current position:
for (i = 0; i < sb->s_blocksize && i < offset; ) {
de = (struct ocfs2_dir_entry *)(bh->b_data + i);
if (le16_to_cpu(de->rec_len) < OCFS2_DIR_REC_LEN(1))
break;
i += le16_to_cpu(de->rec_len);
}
i walks the block on rec_len values taken from the block itself and the
only thing tested is that rec_len is not too small, so a single bogus
rec_len leaves i anywhere in the block, including its last
OCFS2_DIR_REC_LEN(1) - 1 bytes. @offset comes from ctx->pos, which
userspace moves with lseek() on the directory fd, and decides how far the
walk gets.
Two bounds are missing, both of which ocfs2_check_dir_entry() applies for
the emit loop below.
de->rec_len sits at byte offset 8 within the entry, so dereferencing de in
that tail reads past the s_blocksize buffer. ocfs2_check_dir_entry()
declines to look at an entry that close to the end:
size - buf_offset < OCFS2_DIR_REC_LEN(1)
Nothing bounds i += rec_len either, so i can end up past the block. The
emit loop that follows is guarded by offset < sb->s_blocksize and does not
run, but
offset = i;
ctx->pos = (ctx->pos & ~((loff_t)sb->s_blocksize - 1)) | offset;
runs first and ORs a value with bits above the block mask into ctx->pos,
corrupting the block number readdir() resumes from.
ocfs2_check_dir_entry() rejects that as "directory entry overrun":
next_offset = buf_offset + rlen;
... next_offset > size
Apply both bounds. For a consistent directory this changes nothing:
entries are at least OCFS2_DIR_REC_LEN(1) bytes and do not cross the end
of the block, so no valid entry is skipped.
Found by the sashiko review tool; fix approach suggested by Joseph Qi.
Link: https://lore.kernel.org/20260811024337.3972976-1-zhanxusheng@xiaomi.com
Link: https://sashiko.dev/#/patchset/20260806022044.167962-1-zhanxusheng@xiaomi.com
Link: https://lore.kernel.org/20260811024337.3972976-2-zhanxusheng@xiaomi.com
Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com>
Suggested-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Heming Zhao <heming.zhao@suse.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||
|
|
f6f47a9ca8 |
squashfs: avoid thundering-herd cache wakeups
squashfs_cache_get() puts a task to sleep when its block is not cached and
every cache entry is busy. Those sleeps are non-exclusive, so the
nr_exclusive == 1 budget squashfs_cache_put() has always passed to
wake_up() is inert and one release makes every waiter runnable. A wakee
only returns to squashfs_cache_get() if it observes cache->unused before
the entry is reclaimed; later wakees see zero and re-queue inside
wait_event() without rescanning. One freed entry satisfies exactly one
capacity waiter, so waking the rest is waste.
On a Meta production host serving a Python web application from a packaged
squashfs image, a 30-second trace caught 1,045,132 cache-release wake
calls and 19,511,556 wakeups: 18.7 per release, although each release
added only one reusable cache entry. This was causing significant spikes
in CPU usage.
Make the waits exclusive, enqueueing while still holding cache->lock so
that a concurrent lookup either sees the waiter queued or the waiter sees
the block that lookup publishes. Two things follow.
A wakee cannot be assumed to consume the entry it was woken for: it may
find its own block published meanwhile, share that entry, and leave the
freed one unclaimed. So a wakee which shares hands its wakeup on to the
next waiter, as commit
|
||
|
|
1484625c59 |
tracefs updates for v7.3:
- Define event fields before directory creation Move the event_define_fields() call in event_create_dir() before the eventfs directory creation. Previously, a failure after directory creation wouldn't clean up eventfs_inode because the error path didn't call eventfs_remove_dir(). This eliminates the need to clean up the eventfs directories if event_define_fields() fails. - Add warning for out of bounds pos in __eventfs_iterate() Sashiko complains about the ctx->pos causing issues if it is less than 2 or greater than MAX_INT in __eventfs_iterate(). The thing is, the logic prevents that from happening. But to make Sashiko happy, add a WARN_ON() and exit safely if the function ever does get input that is out of the range the function expects. -----BEGIN PGP SIGNATURE----- iIoEABYKADIWIQRRSw7ePDh/lE+zeZMp5XQQmuv6qgUCan+ZvBQccm9zdGVkdEBn b29kbWlzLm9yZwAKCRAp5XQQmuv6qtTfAQC+70AlkM07/RxLkS6GYEEoJ1orM/CO eheyYNZvdjovogEAoUjt0VO+PEcqKDkIdCpx3l9M4hu+B7hN51S2gdEz8gE= =EqMA -----END PGP SIGNATURE----- Merge tag 'tracefs-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace Pull tracefs updates from Steven Rostedt: - Define event fields before directory creation Move the event_define_fields() call in event_create_dir() before the eventfs directory creation. Previously, a failure after directory creation wouldn't clean up eventfs_inode because the error path didn't call eventfs_remove_dir(). This eliminates the need to clean up the eventfs directories if event_define_fields() fails. - Add warning for out of bounds pos in __eventfs_iterate() Sashiko complains about the ctx->pos causing issues if it is less than 2 or greater than MAX_INT in __eventfs_iterate(). The thing is, the logic prevents that from happening. But to make Sashiko happy, add a WARN_ON() and exit safely if the function ever does get input that is out of the range the function expects. * tag 'tracefs-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: eventfs: Add warning for out of bounds pos in __eventfs_iterate() eventfs: Define event fields before directory creation |
||
|
|
59e6295fac |
Driver core changes for 7.3-rc1
- container_of:
- Apply typeof_member(), remove the local __mptr variable to eliminate
variable shadowing warnings on nested container_of() calls, and remove
unnecessary parentheses.
- core:
- Add driver name to probe debug print for initcall_debug.
- Avoid repeatedly printing the same 'Fixed dependency cycle' log.
- Unwind device_add() on attribute creation failure in
attribute_container_add_class_device().
- Remove statistics group if encryption group creation fails in
transport_add_class_device().
- debugfs:
- Fix lockdown check for mmap_prepare().
- Warn if file creation failed due to uninitialized debugfs.
- device property:
- Implement fw_devlink support for software nodes by adding
software_node_add_links(), which creates fwnode links from DEV_PROP_REF
properties to enable automatic probe ordering. Add kunit-managed fwnode
helpers and test coverage.
- Fix infinite loop in fwnode_for_each_child_node() when the secondary fwnode
has more than one child. Add test cases.
- Fix out-of-bounds access in software_node_get_reference_args() when called
with index -1 (UINT_MAX).
- Refactor to use RAII approach with __free().
- Add Bartosz Golaszewski as software node reviewer.
- firmware loader:
- Fix race where a sysfs fallback request can complete before being queued as
pending, leading to a use-after-free on the next fallback request.
- Reject 0-size built-in firmware and fail the build on empty firmware files
in CONFIG_EXTRA_FIRMWARE.
- kobject:
- Provide __KOBJ_ATTR() and __KOBJ_ATTR_RO/WO() initialization macros and
allow the constification of kobject attributes, enabling them to reside in
read-only memory.
- platform:
- Provide platform_device_set_of_node(), platform_device_set_fwnode(), and
platform_device_set_of_node_from_dev() helpers that encapsulate firmware
node reference counting for dynamically allocated platform devices. Convert
all in-tree users that manually assigned dev.of_node or dev.fwnode, fixing a
pre-existing refcount bug in powermac. Switch to counting references of all
firmware node types, not only OF nodes.
- Unify the release path for dynamically allocated platform devices by
removing platform_device_release_full(). Amend the fwnode setter API
contract to warn if a primary software node is overwritten. Add KUnit tests
for correct software node removal on device unregistration.
- Rust:
- Auxiliary:
- Add registration_data_with() closure-based API for invariant ForLt types.
- Debugfs:
- Migrate BinaryWriter and BinaryReaderMut trait requirements from
kernel::transmute traits to zerocopy traits.
- Device:
- Add BoundInternal device context and InternalBoundContext trait for bus
abstractions that need internal access to a bound device.
- Make the lifetime on Core and CoreInternal invariant to prevent coercion
to shorter lifetimes.
- Devres:
- Fix race between concurrent revokers where the losing revoker could return
before the winning revoker finished dropping the inner data, causing
use-after-free.
- Ensure revocation is complete before the device finishes unbinding by
making the synchronization bidirectional.
- Add DevresLt<F: ForLt>, a wrapper around Devres that shortens 'static back
to the caller's borrow scope. Implement ForLt and CovariantForLt for Bar,
IoMem, and ExclusiveIoMem.
- Driver:
- Switch from index-based to pointer-based device ID info lookup, storing
static references in driver_data. Centralize device ID handling in
device_id.rs, removing the open-coded ACPI/OF matching logic and duplicate
ID table from driver.rs.
- I/O:
- Make I/O regions typed (with a dynamically-sized Region type for the
existing untyped case), create view types representing subregions of a
mapped I/O region, and add io_project!() for safely creating subviews.
- Split Io into a base trait (IoBase) and an extension trait (Io) with a
blanket implementation, preventing implementers from overriding provided
methods that unsafe code relies on.
- Add a SysMem backend for shared system memory with volatile access, and
make Coherent implement Io via an I/O view type. Add IoSysMap as sum type
of Mmio and SysMem. Add copying methods (memcpy_{from,to}io()) and
read_val()/write_val() for typed access.
- Replace dma_read!()/dma_write!() with io_read!()/io_write!() for
primitives and copying methods for aggregates; drop the old macros.
Convert nova-core to use I/O projection.
- Fix internal shortcut rule dispatch in the register!() macro, remove
unused rule arguments, and use path fragments for alias destinations.
- IRQ:
- Make irq::Registration compatible with lifetime-bound drivers by
removing the 'static bound on Handler/ThreadedHandler and
replacing Devres<RegistrationInner> with direct
request_irq()/free_irq() calls. Handlers can now directly own
lifetime-bound device resources.
- PCI:
- Convert IrqVectorRegistration to a lifetime-annotated owning type,
giving drivers explicit control over the allocation lifetime.
IrqVector embeds a resolved IrqRequest, making the conversion
infallible. Remove the redundant
request_irq()/request_threaded_irq() wrappers from pci::Device.
- Add pci_irq_type() C helper and expose it via irq_type() on
IrqVectorRegistration and IrqVector, returning PCI_IRQ_MSIX, PCI_IRQ_MSI,
or PCI_IRQ_INTX.
- Mark pci::Device refcount methods inline.
- Serdev:
- Add Rust abstractions for the serial device bus, including serdev::Driver
trait, serdev::Device wrapping struct serdev_device, and serdev::Adapter
implementing RegistrationOps. Includes a sample driver. Markus Probst
takes over as serdev maintainer for both C and Rust code.
- Misc:
- Split ForLt into a base trait (providing the Of<'a> GAT) and an unsafe
CovariantForLt subtrait guaranteeing covariance, enabling invariant types
(e.g. those containing Mutex<&'bound T>) to participate in the ForLt
abstraction.
- Fix Coherent read past EOF returning -ERANGE instead of zero.
- Fix firmware example UB by avoiding null-pointer ARef.
- misc:
- Avoid iattr allocation in kernfs listxattr by using kernfs_iattrs_noalloc().
- Unregister SoC bus on early device registration failure.
- Remove unused DMA_FENCE_TRACE Kconfig symbol.
- Fix /sys/module path in comment.
- Refactor ISA bus init to remove nested blocks.
- Remove redundant nodemask clears in numa_init().
- Add kernel-doc for fwnode_operations and sys_soc.h, mark internal property
data as private for kernel-doc, and add property.h/fwnode.h to driver-api
infrastructure docs.
- Add MAINTAINERS entry for sys_soc.h.
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQS2q/xV6QjXAdC7k+1FlHeO1qrKLgUCaoSPugAKCRBFlHeO1qrK
LlBrAP958EaYZVyfAsqq0EyHv86ahXKWoDDvkwbRUZA5CfV9tAD/bMWVtPLRYaaq
eNEZT7p5w3Haezh61H3c5zpuwFNMTA0=
=VRIa
-----END PGP SIGNATURE-----
Merge tag 'driver-core-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core
Pull driver core updates from Danilo Krummrich:
"container_of:
- Apply typeof_member(), remove the local __mptr variable to
eliminate variable shadowing warnings on nested container_of()
calls, and remove unnecessary parentheses
core:
- Add driver name to probe debug print for initcall_debug
- Avoid repeatedly printing the same 'Fixed dependency cycle' log
- Unwind device_add() on attribute creation failure in
attribute_container_add_class_device()
- Remove statistics group if encryption group creation fails in
transport_add_class_device()
debugfs:
- Fix lockdown check for mmap_prepare()
- Warn if file creation failed due to uninitialized debugfs
device property:
- Implement fw_devlink support for software nodes by adding
software_node_add_links(), which creates fwnode links from
DEV_PROP_REF properties to enable automatic probe ordering. Add
kunit-managed fwnode helpers and test coverage
- Fix infinite loop in fwnode_for_each_child_node() when the
secondary fwnode has more than one child. Add test cases
- Fix out-of-bounds access in software_node_get_reference_args() when
called with index -1 (UINT_MAX)
- Refactor to use RAII approach with __free()
- Add Bartosz Golaszewski as software node reviewer
firmware loader:
- Fix race where a sysfs fallback request can complete before being
queued as pending, leading to a use-after-free on the next fallback
request
- Reject 0-size built-in firmware and fail the build on empty
firmware files in CONFIG_EXTRA_FIRMWARE
kobject:
- Provide __KOBJ_ATTR() and __KOBJ_ATTR_RO/WO() initialization macros
and allow the constification of kobject attributes, enabling them
to reside in read-only memory
platform:
- Provide platform_device_set_of_node(), platform_device_set_fwnode(),
and platform_device_set_of_node_from_dev() helpers that encapsulate
firmware node reference counting for dynamically allocated platform
devices
Convert all in-tree users that manually assigned dev.of_node or
dev.fwnode, fixing a pre-existing refcount bug in powermac. Switch
to counting references of all firmware node types, not only OF
nodes
- Unify the release path for dynamically allocated platform devices
by removing platform_device_release_full(). Amend the fwnode setter
API contract to warn if a primary software node is overwritten. Add
KUnit tests for correct software node removal on device
unregistration
Rust:
- Auxiliary:
- Add registration_data_with() closure-based API for invariant
ForLt types
- Debugfs:
- Migrate BinaryWriter and BinaryReaderMut trait requirements
from kernel::transmute traits to zerocopy traits
- Device:
- Add BoundInternal device context and InternalBoundContext trait
for bus abstractions that need internal access to a bound
device.
- Make the lifetime on Core and CoreInternal invariant to prevent
coercion to shorter lifetimes
- Devres:
- Fix race between concurrent revokers where the losing revoker
could return before the winning revoker finished dropping the
inner data, causing use-after-free.
- Ensure revocation is complete before the device finishes
unbinding by making the synchronization bidirectional.
- Add DevresLt<F: ForLt>, a wrapper around Devres that shortens
'static back to the caller's borrow scope. Implement ForLt and
CovariantForLt for Bar, IoMem, and ExclusiveIoMem
- Driver:
- Switch from index-based to pointer-based device ID info lookup,
storing static references in driver_data. Centralize device ID
handling in device_id.rs, removing the open-coded ACPI/OF
matching logic and duplicate ID table from driver.rs
- I/O:
- Make I/O regions typed (with a dynamically-sized Region type
for the existing untyped case), create view types representing
subregions of a mapped I/O region, and add io_project!() for
safely creating subviews.
- Split Io into a base trait (IoBase) and an extension trait (Io)
with a blanket implementation, preventing implementers from
overriding provided methods that unsafe code relies on.
- Add a SysMem backend for shared system memory with volatile
access, and make Coherent implement Io via an I/O view type.
Add IoSysMap as sum type of Mmio and SysMem. Add copying
methods (memcpy_{from,to}io()) and read_val()/write_val() for
typed access.
- Replace dma_read!()/dma_write!() with io_read!()/io_write!()
for primitives and copying methods for aggregates; drop the old
macros. Convert nova-core to use I/O projection.
- Fix internal shortcut rule dispatch in the register!() macro,
remove unused rule arguments, and use path fragments for alias
destinations
- IRQ:
- Make irq::Registration compatible with lifetime-bound drivers
by removing the 'static bound on Handler/ThreadedHandler and
replacing Devres<RegistrationInner> with direct
request_irq()/free_irq() calls. Handlers can now directly own
lifetime-bound device resources
- PCI:
- Convert IrqVectorRegistration to a lifetime-annotated owning
type, giving drivers explicit control over the allocation
lifetime. IrqVector embeds a resolved IrqRequest, making the
conversion infallible. Remove the redundant
request_irq()/request_threaded_irq() wrappers from pci::Device.
- Add pci_irq_type() C helper and expose it via irq_type() on
IrqVectorRegistration and IrqVector, returning PCI_IRQ_MSIX,
PCI_IRQ_MSI, or PCI_IRQ_INTX.
- Mark pci::Device refcount methods inline
- Serdev:
- Add Rust abstractions for the serial device bus, including
serdev::Driver trait, serdev::Device wrapping struct
serdev_device, and serdev::Adapter implementing
RegistrationOps. Includes a sample driver. Markus Probst takes
over as serdev maintainer for both C and Rust code
- Misc:
- Split ForLt into a base trait (providing the Of<'a> GAT) and an
unsafe CovariantForLt subtrait guaranteeing covariance,
enabling invariant types (e.g. those containing Mutex<&'bound T>)
to participate in the ForLt abstraction.
- Fix Coherent read past EOF returning -ERANGE instead of zero.
- Fix firmware example UB by avoiding null-pointer ARef
misc:
- Avoid iattr allocation in kernfs listxattr by using
kernfs_iattrs_noalloc().
- Unregister SoC bus on early device registration failure.
- Remove unused DMA_FENCE_TRACE Kconfig symbol.
- Fix /sys/module path in comment.
- Refactor ISA bus init to remove nested blocks.
- Remove redundant nodemask clears in numa_init().
- Add kernel-doc for fwnode_operations and sys_soc.h, mark
internal property data as private for kernel-doc, and add
property.h/fwnode.h to driver-api infrastructure docs.
- Add MAINTAINERS entry for sys_soc.h"
* tag 'driver-core-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core: (129 commits)
rust: pci: expose the allocated interrupt type
PCI: Add pci_irq_type() to query the allocated interrupt type
rust: pci: remove request_irq() and request_threaded_irq() from Device
rust: pci: resolve IRQ in index() and embed IrqRequest in IrqVector
rust: pci: convert IrqVectorRegistration to a lifetime-managed owning type
kernfs: avoid iattr allocation in listxattr
rust: serdev: use ThisModule::as_ptr() instead of field access
ACPI/IORT: use platform_device_set_fwnode()
ACPI/APMT: use platform_device_set_fwnode()
firmware_loader: do not queue completed sysfs fallback requests
rust: pci: Mark Device refcount methods inline
rust: irq: make Registration compatible with lifetime-bound drivers
rust: net/phy: remove expansion from doc
rust: dma: return zero for Coherent reads past EOF
rust: io: register: use path fragment for alias destination
rust: io: register: remove unused rule arguments
rust: io: register: dispatch shortcut rules internally
MAINTAINERS: add sys_soc.h to DRIVER CORE
rust: debugfs: remove unsafe blocks from traits impl for Vec
rust: debugfs: migrate debugfs traits requirements to zerocopy
...
|
||
|
|
77d852c763 |
smb/client: fix nlink of an overwritten open file
Reproducer:
1. server: systemctl start ksmbd
2. client: mount with `posix` option
mount -t cifs -o posix //${server_ip}/export /mnt
3. client: touch /mnt/file1 /mnt/file2
4. client: C program: int fd = open("/mnt/file2", O_RDONLY);
5. client: C program: rename("/mnt/file1", "/mnt/file2");
6. client: C program: struct stat stbuf; fstat(fd, &stbuf);
stbuf.st_nlink is 1, should be 0
This patch fixes xfstests generic/035 when mounted with `posix` option.
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
|
||
|
|
60be95527b |
cifs: remove dead size-update blocks in cifs_setattr_unix/nounix
Commit |
||
|
|
297d8026a5 |
cifs: remove redundant size-update block in cifs_remap_file_range()
cifs_remap_file_range() acquires i_rwsem on both inodes via
lock_two_nondirectories() before calling smb2_duplicate_extents().
cifs_setsize() (called inside smb2_duplicate_extents() when the clone
extends the file) therefore already runs under the lock, meaning the
fscache_resize_cookie() added to cifs_setsize() by commit
|
||
|
|
32a7af68df |
cifs: add cifs_resize_file_locked() to guard fscache_resize_cookie() under i_rwsem
cifs_setsize() calls fscache_resize_cookie() without holding i_rwsem.
When the fscache cookie is active (FSCACHE_COOKIE_IS_CACHING is set),
fscache_resize_cookie() performs a real resize that requires i_rwsem
held exclusively. If another file descriptor has the same inode open,
fscache_use_cookie() was already called from that cifs_open(), making
the cookie active. In that case, calling cifs_setsize() from
cifs_do_truncate() (invoked from cifs_open() without i_rwsem) races
against concurrent fscache I/O.
Strip fscache_resize_cookie() from cifs_setsize(), making it a pure
size/page-cache helper. Add cifs_resize_file_locked() for callers
that already hold i_rwsem: it calls netfs_resize_file() and
cifs_setsize(), then temporarily activates the cookie with
fscache_use_cookie() to perform the resize under the lock, then
deactivates it with cifs_fscache_unuse_inode_cookie(). Using
fscache_use_cookie() before the resize ensures correctness whether or
not another fd already holds the cookie active.
Switch cifs_file_set_size(), smb2_duplicate_extents(), and both size-
extension branches of smb3_simple_falloc() to the new wrapper; those
paths already hold i_rwsem via VFS setattr, lock_two_nondirectories(),
or cifs_fallocate() respectively. cifs_do_truncate() continues to
call cifs_setsize() followed by cifs_invalidate_cache(), since it runs
without i_rwsem.
Fixes:
|
||
|
|
364b183230 |
cifs: use cifs_invalidate_cache() in cifs_do_truncate() for O_TRUNC
cifs_do_truncate() is invoked from cifs_open() without i_rwsem, so it
cannot use cifs_resize_file_locked() to perform a proper fscache cookie
resize. Instead, add cifs_invalidate_cache() after cifs_setsize().
cifs_invalidate_cache() calls fscache_invalidate(), which works without
holding i_rwsem: it unconditionally increments inval_counter and sets
FSCACHE_COOKIE_NO_DATA_TO_READ, ensuring that stale cached data is not
served once the cookie is later activated by fscache_use_cookie().
Truncation to zero leaves no valid cached data, making invalidation the
correct semantic here.
Fixes:
|
||
|
|
b1b741cf8e |
smb: client: clear ce->tgthint in free_tgts()
When free_tgts() frees all structures in ce->tlist, ce->tgthint
is left pointing to one of the freed cache_dfs_tgt structures.
If ce->tgthint is not reset before it is used later, it results
in a use-after-free.
Set ce->tgthint to NULL in free_tgts() after the elements are
freed to reflect that no elements remain.
Fixes:
|
||
|
|
bf86c08123 |
smb: client: harden DFS cache against invalid target hints
Currently, get_tgt_name() returns ERR_PTR(-ENOENT) when ce->tgthint is NULL, and dfs_cache_noreq_update_tgthint() assumes ce->tgthint is always valid. In preparation for clearing ce->tgthint in free_tgts(), harden callers of get_tgt_name() against ERR_PTR results and harden dfs_cache_noreq_update_tgthint() against NULL pointer dereferences. Cc: stable@vger.kernel.org Signed-off-by: Fredric Cover <fredric.cover.lkernel@gmail.com> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org> |
||
|
|
b8e5dc4f95 |
smb: client: clear setuid/setgid bit on write with cifsacl/modefromsid/posix extensions
When a file has the setuid or setgid bit set and is written to, the VFS
strips those bits and issues a setattr with ATTR_KILL_SUID/ATTR_KILL_SGID
together with an ATTR_MODE carrying the already-cleared mode.
Both cifs_setattr_unix() and cifs_setattr_nounix() unconditionally dropped
ATTR_MODE in that case:
/* skip mode change if it's just for clearing setuid/setgid */
if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
attrs->ia_valid &= ~ATTR_MODE;
This is fine for the default mount, where the mode is only emulated via
the DOS read-only attribute and cannot represent the setuid/setgid bits
anyway. However, with the "cifsacl" or "modefromsid" mount options the
mode is stored on the server through an ACL (id_mode_to_cifs_acl()), with
the SMB3.1.1 POSIX extensions the mode is sent to the server directly,
and with the SMB1 Unix extensions (cifs_setattr_unix) the mode is sent
via CIFSSMBUnixSetPathInfo(). In all those cases dropping ATTR_MODE means
the cleared mode is never pushed to the server, so the setuid/setgid bit
survives the write.
This is a security issue: on local filesystems the setuid bit is stripped
when a file is written, but over these cifs.ko mounts the bit persists on
the server, potentially allowing an unexpected privilege escalation on
subsequent execution.
Fix this in two places:
1. cifs_setattr_nounix(): only take the "skip mode change" shortcut
when the mode is emulated via the DOS read-only attribute (i.e.
neither cifsacl/modefromsid nor the SMB3.1.1 POSIX extensions are
in effect), so that the cleared mode is propagated to the server
in the ACL / POSIX cases.
2. cifs_setattr_unix(): this function is only called when Unix
extensions are in effect, so the mode is always stored on the
server. Remove the shortcut entirely so that the cleared mode is
always pushed.
Fixes:
|
||
|
|
45f84cf25a |
smb: client: set replay flag on the read send-error retry path
smb2_async_readv() and smb2_async_writev() end with the same
send-error block: if the error is replayable and smb2_should_replay()
agrees, tell netfs to retry the subrequest. The write path also sets
wdata->replay. The read path does not set rdata->replay.
smb2_should_replay() is not a pure predicate. It consumes the retry
budget and computes the exponential back-off, doubling cur_sleep up to
CIFS_MAX_SLEEP. That back-off is only applied where the replay flag is
tested at the top of the reissued request:
if (rdata->replay) {
/* Back-off before retry */
if (rdata->cur_sleep)
msleep(rdata->cur_sleep);
smb2_set_replay(server, &rqst);
}
So on the read path the back-off is recomputed on every send-error
retry and then discarded, and SMB2_FLAGS_REPLAY_OPERATION is not set
on the reissued request.
netfs does not pace the retry either. netfs_reissue_read() calls
->issue_read() directly, and fs/netfs/read_retry.c contains no delay
of its own, so read send-error retries reissue immediately while the
equivalent write retries back off.
The read response callback already sets rdata->replay under the same
conditions, so the read path does use the replay mechanism. Only this
send-error path omits it.
Where the back-off belongs was settled while the commit below was
under review. David Howells asked whether netfslib should be doing the
back-off [1], and objected to sleeping inside the response callback
because that runs in the cifsd thread and would stall the socket [2].
The sleep was therefore taken out of smb2_should_replay() and moved to
just before the replay in smb2_async_readv() and smb2_async_writev()
[3]. Setting the flag here preserves that arrangement: the sleep still
happens at the top of the reissued request, not in a callback.
Set rdata->replay here, matching smb2_async_writev().
Fixes:
|
||
|
|
deb6468f41 |
smb: client: fix request buffer leak in smb2_new_read_req()
smb2_new_read_req() allocates the request buffer with
smb2_plain_req_init() but only publishes it to the caller with
*buf = req at the very end of the function. Two error returns sit in
between:
rc = smb2_plain_req_init(SMB2_READ, io_parms->tcon, server,
(void **) &req, total_len);
if (rc)
return rc;
if (server == NULL)
return -ECONNABORTED;
[...]
rdata->mr = smbd_register_mr(server->smbd_conn,
&rdata->subreq.io_iter,
true, need_invalidate);
if (!rdata->mr)
return -EAGAIN;
On either of them the buffer is neither released nor handed back, so
it is leaked. The caller cannot clean up after it: smb2_async_readv()
does 'goto out' on a non-zero return, which skips the
cifs_small_buf_release(buf) at async_readv_out, and buf has not been
assigned at that point in any case.
The write path has never had this problem. smb2_async_writev()
registers the memory region inline and jumps to its release label
instead of returning:
wdata->mr = smbd_register_mr(...);
if (!wdata->mr) {
rc = -EAGAIN;
goto async_writev_out;
}
Commit
|
||
|
|
a2f9fb451c |
smb/client: return EOPNOTSUPP for unsupported O_TMPFILE
Some SMB servers return STATUS_OBJECT_NAME_NOT_FOUND or
STATUS_DELETE_PENDING when creating an O_TMPFILE.
The SMB client maps them to ENOENT.
The ENOENT error is supposed to be returned when the path
(a target directory in this case) does not exist, while a
lack of support of O_TMPFILE by the target file system should
be indicated by EOPNOTSUPP.
Reported-by: Mikhail Stefantsev <mikhail@mstefan99.com>
Fixes:
|
||
|
|
60038154b4 |
ntfs: do not update ctime when setxattr fails
ntfs_setxattr() updates ctime and marks the inode dirty even when
the operation fails. A failed setxattr(2) must not change file
metadata.
Update ctime only on success.
Fixes:
|
||
|
|
cc9d09fef7 |
ntfs: reject invalid MFT LCNs from boot sector
The NTFS boot sector stores the MFT and MFTMirr locations as unsigned
64-bit LCNs, but parse_ntfs_boot_sector() decoded them into an s64.
A crafted high-bit value could therefore become negative and pass
the existing upper-bound check. The invalid value then propagated into
the MFT zone allocator and could result in an out-of-bounds access to
lcn_empty_bits_per_page.
Fixes:
|
||
|
|
d9e00c457d |
ntfs: serialize resident iomap reads with mrec_lock
ntfs_read_iomap_begin_resident() walks the MFT record through
ntfs_attr_lookup() -> ntfs_attr_find() without taking ni->mrec_lock,
while ntfs_attr_record_resize(), ntfs_make_room_for_attr() and
ntfs_resident_attr_record_add() memmove() the same base_ni->mrec buffer
under that lock. map_mft_record() only takes a reference and does not
serialize, so the reader can observe torn attribute length and offset
fields while a writer is relocating the records.
KCSAN reports the race between the mmap read fault path and both link()
and unlink():
BUG: KCSAN: data-race in ntfs_attr_find / ntfs_attr_record_resize
write to 0xffff888100af1018 of 4 bytes by task 96 on cpu 1:
ntfs_attr_record_resize+0xd2/0x130
ntfs_attr_record_rm+0xad/0x530
ntfs_delete+0x224/0x640
ntfs_unlink+0x14d/0x280
vfs_unlink+0x157/0x520
read to 0xffff888100af1018 of 4 bytes by task 95 on cpu 0:
ntfs_attr_find+0x104/0x5b0
ntfs_attr_lookup+0x39c/0x10c0
ntfs_read_iomap_begin_resident+0xc6/0x230
ntfs_read_iomap_begin+0x5d/0xa0
iomap_iter+0x2e2/0x6e0
iomap_read_folio+0x147/0x2a0
ntfs_read_folio+0x108/0x170
filemap_read_folio+0x35/0x100
filemap_fault+0x993/0x1000
value changed: 0x00000250 -> 0x000001f0
The address is mrec + 0x18, i.e. mft_record.bytes_in_use, and the change
is the 96 bytes of one $FILE_NAME attribute being removed.
Keep base_ni->mrec_lock from the resident read iomap lookup through
iomap_end(). This protects both the attribute walk and the subsequent copy
from iomap->inline_data, which points into the MFT record. The non-resident
path is left alone: ntfs_lookup() already holds the directory inode's
mrec_lock when it reads an index folio through read_mapping_folio(), and
taking the lock in the shared wrapper deadlocks there with recursive locking
on mrec_lock. The comment above the read_mapping_folio() call in
fs/ntfs/dir.c notes the same hazard.
The seek path uses the same lookup helper but does not dereference
iomap->inline_data. Release the lock before returning from that path,
whereas the regular read path records base_ni in iomap->private and releases
the lock from its iomap_end() callback.
Tested with a reproducer that faults in a 16-byte resident file while
another thread runs link()/unlink() on it. Before: 40 KCSAN reports in
about one second. After: no reports in 180 seconds over 206,090 read
iterations and 423,540 link/unlink cycles. A PROVE_LOCKING build shows no
lockdep splat with the same reproducer running for 60 seconds.
Fixes:
|
||
|
|
fea9e4488f |
ntfs: verify run length exceeding volume boundary
The mapping pairs decoder validates that the starting LCN is within the volume but does not check if the run extends beyond the volume boundary. A malformed NTFS image with a crafted mapping pairs array could cause the kernel to access memory beyond the volume boundary, potentially leading to memory corruption and privilege escalation. Add validation to ensure lcn + length stays within nr_clusters. Cc: stable@vger.kernel.org Fixes: b4be3a47f8ba4 ("ntfs: bound the free-cluster bitmap scan to the volume") Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
9badcfb91b |
ntfs: allow index root relocation
Allow a resident attribute record to move to an extent MFT record when the
base record needs room for an attribute list. Retry the root conversion
after creating the list, but do not relocate a root that is already
external.
Roll the root back to the base record if persisting the attribute list
fails, and free extent MFT records left empty by relocation or rollback.
Also preserve bitmap allocation errors in index operations.
Fixes:
|
||
|
|
a83e82b0ec |
ntfs: validate non-resident attribute offsets
ntfs_attr_update_meta() shifts the attribute name when converting between
non-sparse and sparse attributes. Converting to sparse also adds the
compressed_size field before the name and mapping pairs, requiring eight
additional bytes in the attribute record.
However, the validator does not check that name_offset is within safe
boundaries for these operations or that the additional space is available.
A malicious MFT record could set name_offset such that:
1. The name is positioned at the very end of a non-sparse attribute.
Converting to sparse would shift the name forward by 8 bytes,
writing beyond the attribute boundary.
2. The name overlaps with the mapping pairs, causing corruption during
conversion.
Add validation to ensure:
- For named attributes, name_offset is within valid bounds
- Name does not extend beyond the attribute or overlap with mapping pairs
- For non-sparse, non-compressed attributes, eight bytes are available
after mapping_pairs_offset for the compressed_size field
The space check also covers unnamed attributes, for which name_offset = 0
is valid and no name range needs to be checked.
Fixes: 7e2a1c554bc4 ("ntfs: Fix min_len for compressed/sparse attributes in ntfs_non_resident_attr_value_is_valid()")
Cc: stable@vger.kernel.org
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
Co-developed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
|
||
|
|
121dedb3b6 |
ntfs: simplify ntfs_reparse_set_native_symlink()
Avoid redundant 'strlen()' and use the convenient 'strreplace()' to simplify 'ntfs_reparse_set_native_symlink()'. Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
ea6a67ef64 |
ntfs: reject unprivileged writes to reserved $LX* xattrs
Reject setxattr of the reserved $LXUID, $LXGID, $LXMOD and $LXDEV names
from userspace unless the caller has CAP_SYS_ADMIN.
Fixes:
|
||
|
|
19cac7902a |
ntfs: bound the free-cluster bitmap scan to the volume
vol->lcn_empty_bits_per_page is sized from vol->nr_clusters at mount, but
ntfs_cluster_alloc() bounds its scan of that array by the size of $Bitmap.
Those are independent on-disk quantities and the mount-time check only
rejects a $Bitmap that is too small, so an image whose $Bitmap covers more
clusters than the volume has lets the scan index past the array. A run
whose LCN lies in that gap takes the allocator straight there, since the
caller passes the file's own last LCN as its locality hint. KASAN reports
a slab out-of-bounds read when a file on such a volume is extended.
Clamp the scan to what that array covers, mirroring the max_index
calculation the mount-time scan already uses, and reject a decoded LCN
at or beyond nr_clusters in the mapping pairs decoder. Conforming
volumes are unaffected.
Fixes:
|
||
|
|
4d730a4dd7 |
ntfs: respect per-file chmod mode over mount masks
fmask and dmask provide the default permissions for files without WSL
metadata. Once chmod stores a mode in $LXMOD, however, that per-file mode
must take precedence so selected files can retain permissions such as
execute across remounts.
Record whether $LXMOD was found while loading an inode and apply the mount
masks only when it is absent. Do not remask the in-memory mode after
setattr persists it. Continue loading $LXMOD even when optional $LXUID or
$LXGID metadata is missing, since chmod may create only $LXMOD.
Fixes:
|
||
|
|
71feaa7686 |
ntfs: apply Windows name checks only with windows_names
The windows_names mount option is documented to reject names containing
characters forbidden by Windows. However, ntfs_check_bad_windows_name()
unconditionally rejects those characters before checking the mount option.
Move the character validation after the option check so a default NTFS
mount accepts POSIX names such as names containing ':'. Mounts using
windows_names retain the existing Windows-compatible validation, including
reserved device names and trailing spaces or dots.
Fixes:
|
||
|
|
dc09bf79b7 |
ntfs: Fix index_root heap OOB write in ntfs_ir_to_ib()
ntfs_ir_to_ib copies all entries from index_root into a freshly allocated
index_block_size-byte buffer without verifying that the entries fit in the
available space. The entries in index_root may be larger than the usable
entry space in the index block.
This can cause OOB writes past the end of the allocation.
The validator ntfs_index_root_inconsistent() checks that entries are
self-consistent within the IR value, but never cross-checks them against
index_block_size. There is no bounds check in ntfs_ir_to_ib() before the
memcpy.
Fixing this at the sink in ntfs_ir_to_ib() since
ntfs_index_root_inconsistent() validates the logical consistency of
index_root as a structure and a root with large entries is a structurally
valid root. The bug is a size conflict of ntfs_ir_to_ib().
Also, the validator is called once per inode load in
ntfs_read_locked_inode() while ntfs_ir_to_ib() is only called during a
reparent, a check there adds no overhead to the common path.
Moreover, even a future call path that bypasses the validator would still
be protected.
With NULL as first parameter of ntfs_error(), the volume error flag is
never set by this call, so the device name will be absent from the error
message. In any case, that the caller, ntfs_ir_reparent(), prints an error
message that includes the device name on NULL returns.
I think this is the best solution available without adding
'struct super_block *sb' as a parameter to ntfs_ir_to_ib().
This heap out-of-bounds write is triggered by a crafted filesystem image,
which is not in the kernel threat model, anyway, fixing memory errors would
be nice to keep things secure.
Fixes:
|
||
|
|
0ab6dc1ac4 |
ntfs: move attribute payload before shrinking its record
ntfs_new_attr_flags() resizes the non-resident attribute record before moving its name and mapping pairs to their shorter-header offsets when compression or sparse state is cleared. Shrinking the record first moves the following attribute over the tail of the old record. The subsequent memmove() therefore copies bytes from that following attribute instead of the old mapping pairs. Re-enabling compression on an empty file persists those bytes as a malformed mapping pairs array, which ntfsck reports as a missing or invalid run length. Move the payload before shrinking the record, while retaining the existing resize-before-move ordering when growing it. Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
7ed0028126 |
ntfs: fix resident conversion in ntfs_new_attr_flags
When setting sparse/compressed flags on a resident attribute, the function skipped the resident-to-non-resident conversion and terminated. Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
5b676a77f3 |
ntfs: skip reads for full compression unit overwrites
ntfs_compress_write() reads every page in a compression unit before copying new data into it. The read is unnecessary when an aligned write replaces every byte covered by the page-cache folios. Detect full page-aligned compression unit overwrites and grab locked cache folios without reading them. Keep the read-modify-write path for partial units and units that cover only part of a large page. Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
a8a4681f2b |
ntfs: submit one bio per compressed write unit
ntfs_write_cb() allocates a single-vector bio and synchronously submits it whenever another output page cannot be added. A 64 KiB uncompressed unit therefore requires up to sixteen separate bio submissions. Allocate enough vectors for the complete unit, add all output pages, and perform one synchronous submission. Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
8cd2bf1d7a |
ntfs: reuse compression output workspace across write units
ntfs_write_cb() allocates output pages and creates input and output vmaps for every compression unit. Sequential writes repeatedly pay those allocation and page-table costs even though each unit has the same maximum output size. Allocate and map the output workspace once per write request. Access input sub-blocks with kmap_local_page(), and reuse the output pages and mapping for every compression unit in the request. Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
33200693eb |
ntfs: reuse the compression context during writes
ntfs_compress_block() allocates and initializes a roughly 40 KiB match finder context for every 4 KiB sub-block. A 64 KiB compression unit thus performs sixteen large allocations even though the calls are serialized. Allocate one context for the complete write request and reset its hash chains for each sub-block as before. Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
b54559689a |
ntfs: fix initialized size and page state after compressed writes
The write iterator now expands attributes before calling ntfs_compress_write(), so compressed writes must not expand the attribute themselves. However, the compressed path still needs to reject zero-byte iterator copies, advance initialized_size after successful I/O, and invalidate modified folios after a failed compression-unit write. Reject no-progress copies, persist the new initialized size on success, and clear folio uptodate state when the synchronous write fails. Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
eb67671cd8 |
ntfs: write compressed data before replacing old clusters
ntfs_write_cb() punches the old compression unit and publishes the new mapping before submitting the replacement data. An allocation or I/O failure after the punch loses the previous contents and can leave the mapping pointing at unwritten clusters. Allocate and write the replacement clusters first. Replace the runlist only after the synchronous write succeeds, and free new clusters on failure. Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
2bd734ee2c |
ntfs: punch all-zero compressed blocks
When a rewritten compression block consists entirely of zeroes, ntfs_write_cb() returns without replacing its existing runlist mapping. The old on-disk contents therefore remain visible after cache eviction. Punch the compression unit so that reads resolve it as a sparse block and release any clusters that held the previous contents. Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
f2b2aeeaad |
ntfs: support large pages in compressed writes
ntfs_compress_write() derives its page count by shifting the compression block size and assumes that every compression block begins at a page boundary. This produces a zero page count for small compression blocks on large-page systems and ignores an in-page compression block offset. Map every page covering the compression block, pass the in-page offset to ntfs_write_cb(), and stage uncompressed output in page-aligned pages. Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
3e497af637 |
ntfs: propagate compression context allocation errors
ntfs_compress_block() returns -ENOMEM when its compression context cannot be allocated, but its unsigned return type turns the error into a large positive value. ntfs_write_cb() then hides the allocation failure. Use a signed return type and propagate negative errors to the caller. Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
34d22551ad |
ntfs: dir: use kmemdup() instead of kmalloc() and memcpy()
Use kmemdup() instead of a separate kmalloc() and memcpy() pair, simplifying the code while preserving the existing behavior. This issue was reported by memdup.cocci. Signed-off-by: Mohammad Shahid <mdshahid03@gmail.com> Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
eec908b5c0 |
ntfs: mft: use kmemdup() instead of kmalloc() and memcpy()
Use kmemdup() instead of a separate kmalloc() and memcpy() pair, simplifying the code while preserving the existing behavior. This issue was reported by memdup.cocci. Signed-off-by: Mohammad Shahid <mdshahid03@gmail.com> Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
5e150dc65d |
ntfs: reparse: remove redundant NULL checks before kvfree()
kvfree() safely handles NULL pointers, so the explicit NULL checks before calling kvfree() are unnecessary. This issue was reported by ifnullfree.cocci. Signed-off-by: Mohammad Shahid <mdshahid03@gmail.com> Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
5c32f0b8d7 |
ntfs: use pagecache_isize_extended() on size extension
When extending file size, call truncate_pagecache() first, then update i_size, and use pagecache_isize_extended() instead of manual iomap_zero_range(). This ensures the straddling folio is properly marked RO so page_mkwrite() is called and post-EOF area is zeroed. Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
fbd74e665e |
ntfs: file extension before write submission
Prepare non-resident file allocation and initialized-size extension in ->write_iter() before entering the buffered or direct iomap write paths. Previously, the iomap write callback extended initialized_size. When a direct write started beyond initialized_size, ntfs_extend_initialized_size() used iomap_zero_range() to zero the gap through the page cache. This created dirty folios after iomap DIO had invalidated its target cache range. The bsync path then had to synchronously write back the entire zeroed gap to prevent the post-DIO invalidation from encountering a dirty boundary folio. Move allocation and initialized-size preparation ahead of iomap submission. For DIO, kiocb_invalidate_pages() now sees any dirty boundary folio created by iomap_zero_range(), writes it back when necessary, and invalidates it before the direct I/O is issued. This removes the explicit synchronous writeback of the zeroed gap while preserving the required boundary-folio ordering. Keep compressed writes out of the early initialized-size extension so their existing write path can zero uninitialized data before compression. Move compressed-file allocation expansion to write_iter as well, eliminating the now-redundant expansion from ntfs_compress_write(). Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
6e03fbd5f7 |
ntfs: fix kmap_local_page() usage in compress
Several compressed I/O paths discard the address returned by
kmap_local_page() and later access or unmap the page using page_address().
This is invalid for highmem pages, and local mappings must also be unmapped
using the address returned by kmap_local_page().
Map each destination page in ntfs_decompress() only while producing the
current sub-block. Use memcpy_from_page(), memcpy_to_page(), and
memzero_page() for the other page accesses. Remove unnecessary local
mappings from ntfs_write_cb(), where pages are accessed through the vmap()
mapping.
Fixes:
|
||
|
|
f6ce4cbcc5 |
ntfs: Remove references to page->__folio_index
Pages don't have indexes, folios have indexes. Correct this in
ntfs_read_compressed_block() and also remove a use of page->mapping
while I'm in here. Also convert the calls to unlock_page() and
flush_dcache_page().
Fixes:
|
||
|
|
8a81803f87 |
ntfs: Use zero_user_segment() in handle_bounds_compressed_page()
This fixes handle_bounds_compressed_page() on highmem memory
as page_address() does not work on memory which has been kmap_local(),
only on kmap() memory.
Fixes:
|
||
|
|
a3976da121 |
ntfs: Remove use of __folio_index in handle_bounds_compressed_page()
Nobody is supposed to use page->__folio_index. Use page_offset()
instead, and simplify by working exclusively in loff_t instead of mixing
up loff_t and pgoff_t.
Link: https://lore.kernel.org/all/20260608210618.3437216-3-willy@infradead.org/
Fixes:
|
||
|
|
f98d80d517 |
ntfs: Inline zero_partial_compressed_page()
zero_partial_compressed_page() has one caller and the next commit
will make changes to it that make it inelegant to split across two
functions.
Fixes:
|
||
|
|
ffc755828d |
ntfs: Fix min_len for compressed/sparse attributes in ntfs_non_resident_attr_value_is_valid()
Here the attribute validator computes a single min_len = 64 (as the end of initialized_size) for all non-resident attributes regardless of the flags field. This is correct for regular non-resident attributes but for sparse or compressed non-resident attributes the fixed header is 8 bytes longer, it includes a compressed_size field at bytes 64-71, min_len should be 72. Since the validator lets a sparse/compressed attr_record be less than the correct length, caller's accesses to compressed_size (e.g., ntfs_read_locked_inode() or ntfs_attr_update_mapping_pairs()) can extend past the attribute declared boundary. This can cause OOB reads or OOB writes past the MFT record buffer if the attribute is positioned near the end of the MFT record. The compressed_size field is accessed from: - ntfs_read_locked_inode() - ntfs_read_locked_attr_inode() - ntfs_attr_open() - ntfs_attr_update_mapping_pairs() ntfs_attr_make_non_resident() seems to be safe. Fixing this by raising min_len for sparse/compressed attributes in the validator. The OOB reads and the OOB writes require a crafted filesystem image, which is not in the kernel threat model, anyway, fixing memory errors would be nice to keep things secure. Signed-off-by: Alexandro Calo <alexandro.calo@nozominetworks.com> Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
41e1cf4ec1 |
ntfs: rewrite EA stream before updating metadata
Updating an EA removes the old record and appends its replacement.
Build the complete $EA stream in memory and rewrite it from offset zero,
rather than committing a compacted stream followed by a separate append.
generic/642 shows that the append path can leave an invalid record layout
on disk, including when a new EA entry is added.
When removing an EA, write the compacted stream before updating
$EA_INFORMATION and restore the original pair if the metadata update
fails.
When the final EA entry is removed the $EA/$EA_INFORMATION pair is torn
down. If removing $EA_INFORMATION fails after $EA has already been
removed, the original $EA is restored so the two attributes stay
consistent.
Fixes:
|
||
|
|
772e4c8f25 |
ntfs: remove empty EA attribute pair
Removing the final xattr leaves an empty $EA stream. An empty $EA
attribute paired with $EA_INFORMATION is not a valid EA chain and
ntfsck reports it as corrupt.
Remove both attributes when the final EA entry is deleted.
Fixes:
|
||
|
|
650a2751c9 |
ntfs: validate final EA attribute size
A replacement first removes the existing EA record, then adds the
replacement. Check the size of that final $EA stream before mutating
the current stream.
This avoids committing the shortened $EA stream or $EA_INFORMATION before
discovering that the replacement exceeds the AttrDef size limit.
Fixes:
|
||
|
|
94845e2929 |
- How refreshing: no new features but a whole pile of fixes to more or less
serious issues reported by Sashiko along with miscellaneous cleanups all over the place. All except one by Reinette Chatre, the one by Tony Luck -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmqEdnUACgkQEsHwGGHe VUoAYg/+PncYx3N2rKmJ8BpXOClNesiR6yivomKYqGe2SKIipADmie/l03td6/rj FC/uJnTAFpgB3jJSD6N/haC4hOLk590wCdAg204tCIV0eHPoXQ3UJeUt8aPBOeYK cMt3KlbKrLWulT8DkpnK8GWWEQsrvz+ah9Xmn4s9pw4oo4D4lNZMpWonTiQWENwZ If8KekkiztxZgEIbHKBNEk2Bt5SHhaICcwwaJAnPtCtrL762xqRRXvrZ/kvzebbu zTxkyEciTMqB+4TrbGy9EoWd0KsXsCqL4FtVa/yxu0M/dokHxNE/0xQQwyGcGzBP IYsnPchX/OuqJNGDTaf6WvBhkXBUZLngTA2ZzqVVSnBDmKEkFYYpHNvQGD52eLUE 25zLYdtMvBht1+opQ++w1gMBsq/eUCADB+a1SDPg+RsR0HDi1TUDRmvHY3x/2UK7 opsrnxv1ADGzMefloXqM5we2K3pScKAgc+v4MR+m5gDkTonmoDxS27XVtslrQYy1 LqCqKiK7z3tHL/zYOCcTYXhmlacpuL+1DsnreTdxn4eZ+PieihoAE02Jhh/R2t0N 6LhRF3sIDonHC+L4gXo2f7Agyg5z4jpZBikaO5QxSYAmeqlorzrPYQb2frf3xIL2 0z4Zvl81Ch8FE80Ro/wlucp13gF2wWvxyqnu02+M7xj93YgJ+60= =aMLV -----END PGP SIGNATURE----- Merge tag 'x86_cache_for_v7.3_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull x86 resource control updates from Borislav Petkov: - How refreshing: no new features but a whole pile of fixes to more or less serious issues reported by Sashiko along with miscellaneous cleanups all over the place. All except one by Reinette Chatre, the one by Tony Luck. * tag 'x86_cache_for_v7.3_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: fs/resctrl: Inform user space when status buffer overflowed fs/resctrl: Communicate resource group deleted error via last_cmd_status fs/resctrl: Add last_cmd_status support for writes to max_threshold_occupancy fs/resctrl: Change last_cmd_status custom during input parsing fs/resctrl: Use accurate and symmetric exit flows fs/resctrl: Pass error reading event through to user space fs/resctrl: Use accurate type for rdt_resource::rid fs/resctrl: Change pattern used to track number of entries in enum resctrl_conf_type x86/resctrl: Protect against bad shift fs/resctrl: Use correct format specifier for printing error pointers fs/resctrl: Fix UAF from worker threads when domains are removed x86/resctrl: Ensure domain fully initialized before placed on RCU list fs/resctrl: Prevent deadlock and use-after-free in info file handlers fs/resctrl: Prevent use-after-free in rdtgroup_kn_put() fs/resctrl: Fix deadlock on errors during mount fs/resctrl: Move functions to avoid forward references in subsequent fixes x86,fs/resctrl: Document safe RCU list traversal |
||
|
|
d1dbc59200 |
fuse: wake one waiter per freed slot when raising max_background
fuse_get_req() parks background allocations on fch->blocked_waitq via wait_event_state_exclusive(), so each wakeup releases exactly one waiter. fuse_chan_max_background_set() clears fch->blocked when the new limit exceeds num_background, but the accompanying wake_up() releases a single waiter regardless of how many slots just became available. Raising max_background from 10 to 100 therefore admits one request instead of ninety. The remaining waiters are not permanently stranded — the "else if (!fch->blocked)" branch in fuse_request_end() wakes one more per completion — but that only helps while requests keep completing. Consider a fixed pool of threads doing readahead or async direct I/O with the quota exhausted: every thread is either in flight or parked, and each completion wakes one waiter while freeing one slot, a net change of zero. num_background oscillates around the old limit and the added quota is never taken up. Waking one waiter per freed slot also preserves submission order: once fch->blocked is clear, new callers of fuse_get_req() skip the waitqueue entirely, overtaking waiters that parked before the limit was raised. Use wake_up_nr() with the number of slots that just became available. Since the wakeup is guarded by !fch->blocked, num_background is strictly below max_background, so the count is at least 1 and never degenerates into wake_up_all(). Signed-off-by: Baokun Li <libaokun@linux.alibaba.com> Reviewed-By: Horst Birthelmer <hbirthelmer@ddn.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> |
||
|
|
b773346540 |
fuse: use min_not_zero() in fuse_init_server_timeout()
fuse_init_server_timeout() limits timeout to fuse_max_req_timeout with the same logic as min_not_zero(), and returns early exactly when the computed timeout would be zero. So use min_not_zero() instead and return when the computed timeout is zero. No functional change. Signed-off-by: Sang-Heon Jeon <ekffu200098@gmail.com> Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> |
||
|
|
fd10f40af3 |
fuse: copy request headers via a stack buffer for io-uring
The fuse-io-uring transport copies req->in.h out to the ring in
fuse_uring_copy_to_ring() and req->out.h back in fuse_uring_commit().
Both headers live inside the fuse_request slab object, whose cache
(fuse_req_cachep) is created without a usercopy whitelist, so copying
them directly to/from userspace trips CONFIG_HARDENED_USERCOPY and
panics:
usercopy: Kernel memory exposure attempt detected from SLUB object
'fuse_request' (offset 56, size 40)!
kernel BUG at mm/usercopy.c:102!
Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
RIP: 0010:usercopy_abort (mm/usercopy.c:90)
Call Trace:
__check_heap_object (mm/slub.c:8268)
__check_object_size (mm/usercopy.c:197 mm/usercopy.c:258 mm/usercopy.c:223)
copy_header_to_ring (fs/fuse/dev_uring.c:618)
fuse_uring_prepare_send (fs/fuse/dev_uring.c:776 fs/fuse/dev_uring.c:785)
fuse_uring_send_in_task (fs/fuse/dev_uring.c:1306)
tctx_task_work_run (io_uring/tw.c:96)
task_work_run (kernel/task_work.c:233)
io_run_task_work (io_uring/tw.h:84)
io_cqring_wait (io_uring/wait.c:278)
__do_sys_io_uring_enter (io_uring/io_uring.c:2685)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
Bounce both headers through an on-stack copy so the usercopy touches
stack memory, not the slab object.
Fixes:
|
||
|
|
4332cf75e4 |
fuse: give wakeup hints to the scheduler for synchronous requests
When a synchronous FUSE request is sent, the in-kernel client queues it
on fiq->pending and wakes the userspace daemon sleeping in
fuse_dev_do_read()->wait_event_interruptible_exclusive(fiq->waitq, ...).
The client then blocks in request_wait_answer() waiting for the reply,
so the waker is about to go to sleep: this is exactly the pattern that
WF_SYNC is meant to optimise.
As Peter Zijlstra explained in the earlier discussion [1],
WF_SYNC is a hint that the waker is about to sleep and the waker and
wakee share data, so stacking the woken thread on the current CPU
is beneficial for cache locality instead of searching for an idle one.
Add a wake_up_sync() wrapper for task on the synchronous request path.
Performance:
On an Android big.LITTLE device where the FUSE daemon (MediaProvider)
runs as a background service on the little cores while foreground
applications run on the big cores, the synchronous wakeup hint lets
the scheduler pull the daemon thread onto the big core that is
issuing the request, where the request data is cache-hot. Measured
by qixiaoyu [2] on a 2000-picture zip decompression to /sdcard:
------------------------------------------
| Default | patched | Improvement |
------------------------------------------
| 13.0 s | 7.0 s | 46% |
------------------------------------------
Server thread wall duration: 3583 ms -> 1276 ms
Server runs on big core: 5% -> 79%
The original 4K-file copy/compress/decompress workload [1] on the
same kind of device showed a ~28% improvement (13.8s -> 9.9s).
Note: Miklos reported [2] that on his test box he could not observe
an actual migration from wake_up_interruptible_sync(); the benefit
appears to be most visible on asymmetric topologies (big.LITTLE,
where the daemon normally lives on a little core) and on workloads
dominated by small synchronous requests. No regression was
reported on the symmetric- SMP test setups tried.
The earlier version of this change [1] added a `bool sync` argument
to all three hooks of `struct fuse_iqueue_ops` and threaded it
through virtio_fs as well. Miklos questioned the interface churn,
and the patch has been stalled since.
Re-work it so the exported interface is left alone. The hint is
carried in a new FR_SYNC_WAKEUP bit of the existing `fuse_req->flags`
bitfield (an `unsigned long`, so no layout change):
- __fuse_request_send() sets the flag before fuse_send_one().
- fuse_dev_queue_req() consumes it with test_and_clear_bit() and
forwards the result to fuse_dev_wake_and_unlock(), which then
picks wake_up_sync() or wake_up().
- The forget, interrupt and resend paths pass `false` explicitly,
preserving their original wake_up() behaviour.
Only /dev/fuse ever wakes fiq->waitq; virtio_fs and fuse_uring
dispatch through their own transport and never call wake_up(), so
threading `sync` through their ops would just add an unused argument.
test_and_clear_bit() makes the flag a one-shot hint that cannot leak
into a future requeue, and no extra cleanup is needed in
fuse_request_end()/fuse_put_request().
[1] https://lore.kernel.org/lkml/1638780405-38026-1-git-send-email-quic_pragalla@quicinc.com/
[2] https://lore.kernel.org/lkml/20221222093407.GA1141@mi-HP-ProDesk-680-G4-MT/
This work is based on "Pradeep P V K <quic_pragalla@quicinc.com>" and
"Pavankumar Kondeti <quic_pkondeti@quicinc.com>"
Assisted-by: TRAE:GLM-5.2
Signed-off-by: Xuewen Yan <xuewen.yan@unisoc.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
|
||
|
|
928f659a3e |
fuse: check for NULL root inode in fuse_fill_super_submount
fuse_iget() can return NULL when its inode allocation fails, but
fuse_fill_super_submount() passed the result straight to get_fuse_inode()
and decremented fi->nlookup without checking it:
root = fuse_iget(sb, parent_fi->nodeid, ...);
fi = get_fuse_inode(root);
fi->nlookup--;
Inside fuse_iget() the inode allocation can fail and return NULL. The
submount root takes the iget5_locked() path, whose alloc_inode() can fail
under memory pressure (the auto-submount branch can fail the same way in
new_inode() or fuse_alloc_submount_lookup()):
inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set,
&nodeid);
if (!inode)
return NULL;
A NULL root makes get_fuse_inode() a container_of() on NULL and the
nlookup decrement a write to a bogus address, oopsing the mount. With
CONFIG_KASAN the following null pointer dereference is reported when the
root inode allocation of an auto-submount fails (e.g. under memory
pressure):
==================================================================
BUG: KASAN: null-ptr-deref in fuse_get_tree_submount+0x656/0x8b0
Read of size 8 at addr 00000000000002b0 by task ls/942
CPU: 0 PID: 942 Comm: ls Tainted: G W 6.6 #15
Call Trace:
<TASK>
fuse_get_tree_submount+0x656/0x8b0
vfs_get_tree+0x48/0x140
fc_mount+0x13/0x50
fuse_dentry_automount+0x7a/0xb0
__traverse_mounts+0xca/0x330
step_into+0x339/0xac0
path_lookupat+0xc5/0x2f0
filename_lookup+0x163/0x2a0
vfs_statx+0xd5/0x200
do_statx+0x83/0xd0
__x64_sys_statx+0xa0/0xc0
do_syscall_64+0x37/0x90
entry_SYSCALL_64_after_hwframe+0x78/0xe2
</TASK>
==================================================================
Return -ENOMEM instead; the caller tears down the partially built
superblock on error, matching the other error returns in this
function.
Fixes:
|
||
|
|
ed97699493 |
fuse: reject a duplicate fd= mount option
fuse_opt_fd() stored the fuse device in ctx->fud and bumped its refcount
unconditionally:
ctx->fud = fuse_dev_grab(file);
If fd= is given twice (two fsconfig FSCONFIG_SET_FD calls), the second
call overwrites ctx->fud and grabs the new device, while the reference
taken on the first device is never released - a permanent refcount leak
that pins the first fuse_dev until reboot.
Reject a second fd= outright. ctx is zeroed on allocation, so a non-NULL
ctx->fud reliably means the option was already processed.
Fixes:
|
||
|
|
c22f91d82c
|
fs/ntfs3: validate ef->size covers the record's name and value
When an EA record has a non-zero ef->size, ntfs_read_ea() only checks
that the record fits in the remaining buffer (ea_size > bytes), not that
ef->size is large enough to hold the record's own name_len + 1 + elength.
A crafted image can pass validation with, e.g., ef->size = 24 but
elength = 0xffff. ntfs_get_ea() then trusts elength and copies it out of
the undersized record, reading past the kmalloc(info->size) allocation
and leaking heap memory to userspace via getxattr():
BUG: KASAN: slab-out-of-bounds in ntfs_get_ea (fs/ntfs3/xattr.c:302)
Read of size 65535 at addr ffff888100794550 by task exploit
__asan_memcpy (mm/kasan/shadow.c:105)
ntfs_get_ea (fs/ntfs3/xattr.c:302)
ntfs_getxattr (fs/ntfs3/xattr.c:848)
__vfs_getxattr (fs/xattr.c:441)
vfs_getxattr (fs/xattr.c:474)
do_getxattr (fs/xattr.c:800)
path_getxattrat (fs/xattr.c:868)
do_syscall_64 (arch/x86/entry/syscall_64.c:94)
The buggy address is located 80 bytes inside of
allocated 84-byte region in cache kmalloc-96
Compute the size the record needs and require ef->size to cover it.
Fixes:
|
||
|
|
de603b9d37
|
fs/ntfs3: fix out-of-bounds read in read_log_rec_buf()
read_log_rec_buf() copies a log record into a caller buffer starting at
u32 off = lsn_to_page_off(log, lsn) + log->record_header_len;
log->record_header_len (and log->data_off, used for the following pages)
comes verbatim from the on-disk restart area and is only checked for
8-byte alignment in is_rst_area_valid(), so off can exceed
log->page_size. "tail = log->page_size - off" then underflows and
memcpy() reads past the page_size-sized buffer returned by
read_log_page(), spilling adjacent slab memory into the replay buffer.
This is reachable by mounting a crafted NTFS image:
BUG: KASAN: slab-out-of-bounds in read_log_rec_buf+0x216/0x580
Read of size 64 at addr ffff88800a877ff8 by task exploit/127
read_log_rec_buf fs/ntfs3/fslog.c:2299
log_replay fs/ntfs3/fslog.c:4216
ntfs_loadlog_and_replay fs/ntfs3/fsntfs.c:324
ntfs_fill_super fs/ntfs3/super.c:1392
get_tree_bdev_flags fs/super.c:1694
__x64_sys_mount fs/namespace.c:4360
The buggy address is located 4088 bytes to the right of
the 4096-byte region [ffff88800a876000, ffff88800a877000)
Reject an in-page offset outside the current page before the copy.
Fixes:
|
||
|
|
4deb3edead |
cuse: wait for pending RCU callbacks on module exit
Since commit |
||
|
|
a927f1867e |
fuse: fix invalidate lock leak on open O_TRUNC DAX failure
fuse_open() takes filemap_invalidate_lock() for a DAX truncate
(dax_truncate = true) and releases it before the out_inode_unlock
label. But when fuse_dax_break_layouts() fails, the goto
out_inode_unlock skips the unlock and leaks the rwsem, so any later
fault or truncate on the file stalls on the stale lock.
fuse_dax_break_layouts() can fail with -ERESTARTSYS when a signal
interrupts the wait for busy DAX pages to drain:
open("file", O_RDWR | O_TRUNC)
└─ fuse_open()
├─ filemap_invalidate_lock() # dax_truncate
└─ fuse_dax_break_layouts()
└─ dax_break_layout()
└─ wait_page_idle() # TASK_INTERRUPTIBLE
└─ fuse_wait_dax_page() # unlock, schedule, re-lock
└─ signal → -ERESTARTSYS
goto out_inode_unlock # <- lock leaked
Fix this by moving filemap_invalidate_unlock() below the label so
that all error paths release the lock, and rename the label to
out_unlock as it now covers more than just the inode lock.
Fixes:
|
||
|
|
9afeca0d56 |
fuse: fix invalidate lock leak on setattr writeback failure
fuse_do_setattr() takes filemap_invalidate_lock() for a DAX truncate
(fault_blocked = true) and releases it at the out:/error: labels. But
when a writeback flush is also needed, a write_inode_now() failure
returns directly and leaks the lock, so any later fault or truncate on
the file stalls on the stale rwsem.
For example, truncate(2) on a setuid file reaches fuse_do_setattr()
with both ATTR_SIZE and ATTR_MODE set:
truncate(2)
└─ do_truncate()
├─ dentry_needs_remove_privs() # S_ISUID
└─ notify_change() # KILL_SUID -> ATTR_MODE
└─ fuse_setattr() # no killpriv:
│ # ia_valid |= ATTR_MODE
└─ fuse_do_setattr()
├─ filemap_invalidate_lock() # IS_DAX && is_truncate
└─ write_inode_now() # is_wb && ATTR_MODE
└─ if (err) # e.g. daemon -> -EIO
return err # <- lock leaked
Fix this by adding an unlock label that releases the lock before
returning the error, and use it for the fuse_dax_break_layouts()
failure path as well.
Fixes:
|
||
|
|
d47db9bf50 |
Crypto library updates for 7.3
Add library APIs for most AES encryption modes that are used in the
kernel (ECB, CBC, CBC-CTS, CTR, XCTR, XTS, GCM, CCM).
These AES modes have many in-kernel users that are currently using the
crypto_skcipher or crypto_aead APIs. These existing APIs are difficult
to use and inefficient. Until now, the lack of proper library support
for these has been the main gap in the crypto library.
This set of changes is the next stage of addressing it:
- Implement the new APIs on top of the existing support for
single-block AES in the library.
- Fully document the new APIs.
- Migrate the only user of the old AES-GCM library API to the new,
more flexible API; then remove the old API and its implementation.
- Wire up the new APIs to the traditional crypto API by adding
crypto_skcipher and crypto_aead algorithms.
This makes the new APIs be covered by the traditional crypto API's
self-tests. It also makes them be already used for real on systems
that don't have architecture-optimized code for these modes.
But most importantly, this is a prerequisite for migrating the
architecture-optimized code for these AES modes (i.e.
arch/*/crypto/aes*) into the library, which as usual will
eliminate a lot of redundant "glue" code.
Note that unlike some of the other algorithms that have been migrated
to the library, e.g. SHA-512, for these AES modes there was too much
to get done in one cycle. Nor did it make sense to handle these modes
one at a time, because they tend to be coupled together or depend on
each other, especially in the architecture-optimized AES code.
Thus, most of the benefits (reductions in lines of code, performance
improvements, etc.) will follow in later cycles when
architecture-optimized code is migrated into the library and users of
crypto_skcipher and crypto_aead are updated to use the new APIs.
The design of the new APIs was informed by writing proof-of-concept
patches for many kernel subsystems currently accessing these same
algorithms via crypto_skcipher or crypto_aead (patches 18-33 of
https://lore.kernel.org/r/20260707053503.209874-1-ebiggers@kernel.org/).
While those patches will be resent for real later, the total diffstat
for them was negative 1905 lines. So clearly the new APIs are quite a
bit easier to use and align better with what users actually need.
Besides the new AES encryption APIs, there are also a few changes for
improved AES-CMAC key and context zeroization.
-----BEGIN PGP SIGNATURE-----
iIoEABYIADIWIQSacvsUNc7UX4ntmEPzXCl4vpKOKwUCaoEqhRQcZWJpZ2dlcnNA
a2VybmVsLm9yZwAKCRDzXCl4vpKOKy8YAP4o44z09KdugtigFIFX7qQnLk0uPAw+
sTPqmu+FA4jOGAD/Vy23hzAVpWmSBFhyo7HMK9W0ABK7cqj6x23I/N6JRgM=
=SLPT
-----END PGP SIGNATURE-----
Merge tag 'libcrypto-updates-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux
Pull crypto library updates from Eric Biggers:
"Add library APIs for most AES encryption modes that are used in the
kernel (ECB, CBC, CBC-CTS, CTR, XCTR, XTS, GCM, CCM).
These AES modes have many in-kernel users that are currently using the
crypto_skcipher or crypto_aead APIs. These existing APIs are difficult
to use and inefficient. Until now, the lack of proper library support
for these has been the main gap in the crypto library.
This set of changes is the next stage of addressing it:
- Implement the new APIs on top of the existing support for
single-block AES in the library.
- Fully document the new APIs.
- Migrate the only user of the old AES-GCM library API to the new,
more flexible API; then remove the old API and its implementation.
- Wire up the new APIs to the traditional crypto API by adding
crypto_skcipher and crypto_aead algorithms.
This makes the new APIs be covered by the traditional crypto API's
self-tests. It also makes them be already used for real on systems
that don't have architecture-optimized code for these modes.
But most importantly, this is a prerequisite for migrating the
architecture-optimized code for these AES modes (i.e.
arch/*/crypto/aes*) into the library, which as usual will eliminate
a lot of redundant "glue" code.
Note that unlike some of the other algorithms that have been migrated
to the library, e.g. SHA-512, for these AES modes there was too much
to get done in one cycle. Nor did it make sense to handle these modes
one at a time, because they tend to be coupled together or depend on
each other, especially in the architecture-optimized AES code.
Thus, most of the benefits (reductions in lines of code, performance
improvements, etc.) will follow in later cycles when
architecture-optimized code is migrated into the library and users of
crypto_skcipher and crypto_aead are updated to use the new APIs.
The design of the new APIs was informed by writing proof-of-concept
patches for many kernel subsystems currently accessing these same
algorithms via crypto_skcipher or crypto_aead (patches 18-33 of
https://lore.kernel.org/r/20260707053503.209874-1-ebiggers@kernel.org/).
While those patches will be resent for real later, the total diffstat
for them was negative 1905 lines. So clearly the new APIs are quite a
bit easier to use and align better with what users actually need.
Besides the new AES encryption APIs, there are also a few changes for
improved AES-CMAC key and context zeroization"
* tag 'libcrypto-updates-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux:
mac80211: fils_aead: Use __cleanup() instead of memzero_explicit()
Bluetooth: SMP: clear the aes_cmac_key when done
smb: clear the aes_cmac_key and aes_cmac_ctx when done
lib/crypto: aes-cmac: Add zeroization functions
lib/crypto: aesgcm: Remove old AES-GCM library
x86/sev: Remove obsolete virtual address check
x86/sev: Use new AES-GCM library
crypto: aes - Add CCM support using library
crypto: aes - Add GCM support using library
crypto: aes - Add XTS support using library
crypto: aes - Add CTR and XCTR support using library
crypto: aes - Add CBC and CBC-CTS support using library
crypto: aes - Add ECB support using library
lib/crypto: aes: Add CCM support
lib/crypto: aes: Add GCM support
lib/crypto: aes: Add XTS support
lib/crypto: aes: Add CTR and XCTR support
lib/crypto: aes: Add CBC and CBC-CTS support
lib/crypto: aes: Add ECB support
crypto: xts - Split out __xts_verify_key() helper
|
||
|
|
1d7443e4dc |
fscrypt updates for 7.3
The main change this cycle is a significant simplification that's been
overdue for a while now: standardizing on a single file contents
encryption implementation in ext4 and f2fs, instead of having two.
Specifically, the original filesystem-layer file contents encryption
implementation is removed, and the blk-crypto implementation is now
used unconditionally. blk-crypto delegates either to inline crypto
hardware or to the CPU via blk-crypto-fallback. The latter is
functionally equivalent to the original filesystem-layer code.
The blk-crypto implementation already existed, but previously it was
used only when the filesystem was mounted with "-o inlinecrypt". Now,
"-o inlinecrypt" just selects whether inline crypto hardware is used.
To allow maintaining that user control over hardware use, the
blk-crypto API is extended with a new flag BLK_CRYPTO_CFG_ALLOW_HW.
Overall, this removes quite a bit of redundant code from ext4, f2fs,
and fs/crypto/. It should make things easier for ongoing filesystem
efforts such as iomap support, large folios, and btrfs encryption.
(btrfs had already been planning to use blk-crypto exclusively.)
There are two small behavior changes of note:
- Direct I/O now works on encrypted files even without
"-o inlinecrypt", rather than falling back to buffered I/O. This is
effectively a bugfix, though I'll continue to keep an eye out for
any user that may have been depending on the buffered I/O fallback.
- IV_INO_LBLK_32 policies are no longer supported in certain cases
that didn't make sense and have no known uses.
This has been in linux-next since July 22 with no reported issues.
All encryption xfstests pass on ext4 and f2fs. As usual I've also been
using it on a system with an fscrypt-encrypted home directory. Of
course, the blk-crypto code paths also aren't new and were already
being used on many systems via the inlinecrypt mount option.
In addition to the main change described above, there are a few other
cleanups such as using lock guards for mutexes, improving
documentation, and removing a workaround for outdated gcc versions.
-----BEGIN PGP SIGNATURE-----
iIoEABYIADIWIQSacvsUNc7UX4ntmEPzXCl4vpKOKwUCaoDumhQcZWJpZ2dlcnNA
a2VybmVsLm9yZwAKCRDzXCl4vpKOKwk1AP9gAHdxAK2tr+Wpklkos/qTMR3a7h2I
xLmgwhLHmHoHTgD/cD+0eMoK4RIVVGS/73Bf7oF2qY5jOyfi1aGh4ERQ0AA=
=0+o6
-----END PGP SIGNATURE-----
Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/linux
Pull fscrypt updates from Eric Biggers:
"The main change this cycle is a significant simplification that's been
overdue for a while now: standardizing on a single file contents
encryption implementation in ext4 and f2fs, instead of having two.
Specifically, the original filesystem-layer file contents encryption
implementation is removed, and the blk-crypto implementation is now
used unconditionally. blk-crypto delegates either to inline crypto
hardware or to the CPU via blk-crypto-fallback. The latter is
functionally equivalent to the original filesystem-layer code.
The blk-crypto implementation already existed, but previously it was
used only when the filesystem was mounted with "-o inlinecrypt". Now,
"-o inlinecrypt" just selects whether inline crypto hardware is used.
To allow maintaining that user control over hardware use, the
blk-crypto API is extended with a new flag BLK_CRYPTO_CFG_ALLOW_HW.
Overall, this removes quite a bit of redundant code from ext4, f2fs,
and fs/crypto/. It should make things easier for ongoing filesystem
efforts such as iomap support, large folios, and btrfs encryption
(btrfs had already been planning to use blk-crypto exclusively.)
There are two small behavior changes of note:
- Direct I/O now works on encrypted files even without "-o inlinecrypt",
rather than falling back to buffered I/O. This is effectively a
bugfix, though I'll continue to keep an eye out for any user that
may have been depending on the buffered I/O fallback.
- IV_INO_LBLK_32 policies are no longer supported in certain cases
that didn't make sense and have no known uses.
This has been in linux-next since July 22 with no reported issues. All
encryption xfstests pass on ext4 and f2fs. As usual I've also been
using it on a system with an fscrypt-encrypted home directory. Of
course, the blk-crypto code paths also aren't new and were already
being used on many systems via the inlinecrypt mount option.
In addition to the main change described above, there are a few other
cleanups such as using lock guards for mutexes, improving
documentation, and removing a workaround for outdated gcc versions"
* tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/linux: (29 commits)
blk-crypto: Update docs for blk-crypto-fallback motivation
blk-crypto: Remove unused function blk_crypto_config_supported()
fscrypt: Update docs for data path
fscrypt: Remove unused function fscrypt_finalize_bounce_page()
f2fs: Update outdated comment in f2fs_write_begin()
fs: Update outdated comment for SB_INLINECRYPT
fscrypt: Update encryption policy version docs
fscrypt: Replace some variable-size memsets with fixed-size
fscrypt: Add safety checks to non-block-based en/decryption
fscrypt: Merge bio.c and inline_crypt.c into block.c
fscrypt: Remove unused functions and workqueue
fscrypt: Remove fs-layer zeroout code
fscrypt: Remove fscrypt_dio_supported()
fscrypt: Replace calls to fscrypt_inode_uses_inline_crypto()
fs/buffer: Remove fs-layer decryption code
f2fs: Remove fs-layer file contents en/decryption code
ext4: Further de-generalize the bio postprocessing code
ext4: Make ext4_bio_write_folio() return void
ext4: Remove fs-layer file contents en/decryption code
Documentation: fscrypt: Update docs for inlinecrypt
...
|
||
|
|
63c070cba0 |
nilfs2 updates for v7.3
- nilfs2: standardize the inode number type to u64
- nilfs2: enhance btree node keys check
- nilfs2: suppress false positive WARN_ONs for sufile after an FS error
- nilfs2: fix BUG in nilfs_copy_dirty_pages() on dirty state mismatch
- nilfs2: prevent out-of-bounds read in super root block parsing
- nilfs2: fix infinite loop in nilfs_clean_segments()
- nilfs2: fix slab-out-of-bounds in nilfs_direct_propagate after truncation
- Documentation: fix grammar in description of nilfs2 recovery code
- nilfs2: handle corrupted checkpoint count gracefully during deletion
- nilfs2: reject invalid block index in GC ioctl
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQT4wVoLCG92poNnMFAhI4xTh21NnQUCaoNiIQAKCRAhI4xTh21N
nW+YAQCIBwhBkHCHiBPeupSxYar35F/+f5xj4JCh0j6PrbwbYAEAyGJRw9QJNczy
rIVKmh2yuqyukCnPGFRFVBJQAFXHHQQ=
=M3Sh
-----END PGP SIGNATURE-----
Merge tag 'nilfs2-v7.3-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/vdubeyko/nilfs2
Pull nilfs2 updates from Viacheslav Dubeyko:
"This contains fixes of syzbot reported issue and various fixes in
NILFS2 functionality:
- Reject super-root inode sizes whose computed on-disk footprint
exceeds the filesystem block size (David Lee)
- Replace WARN_ON() in nilfs_cpfile_delete_checkpoints() with
returning -EIO and reporting a filesystem error via nilfs_error()
in the case of corrupted checkpoint count on the storage medium
(Igor Putko)
- Fixed a potential infinite loop in nilfs_clean_segments() reported
by syzbot (Joshua Crofts)
In nilfs_clean_segments(), if err is non-zero, logic logs the error
and sleeps but doesn't abort when it encounters a terminal error
like -EROFS. This causes the thread to loop forever.
Fix this by breaking out of the loop if nilfs_segctor_construct()
returns -EROFS.
- Fix small grammar mistake in the description for nilfs2 recovery
code (Manoj K M)
- Multiple fixes by Ryusuke Konishi:
- fix the list corruption issue recently detected by syzbot, that
can occur when out-of-range values are intentionally passed to
certain GC ioctl parameters
- fix a flaw in the original B-tree implementation related to
truncation and resolves the reported out-of-bounds memory
access issue
- fix an issue reported by syzbot where a kernel BUG could be
triggered depending on timing after filesystem corruption is
detected
- fix an issue where a WARN_ON check is triggered by sufile
functions within the log writer after the filesystem degrades
to read-only mode
- Check for sorted keys when reading btree node blocks into the cache
(Wang Jianjian)
This prevents unexpected errors during the block number assignment
phase in log writing caused by key order inconsistencies, as well
as the kernel warnings reported by syzbot"
* tag 'nilfs2-v7.3-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/vdubeyko/nilfs2:
nilfs2: standardize the inode number type to u64
nilfs2: enhance btree node keys check
nilfs2: suppress false positive WARN_ONs for sufile after an FS error
nilfs2: fix BUG in nilfs_copy_dirty_pages() on dirty state mismatch
nilfs2: prevent out-of-bounds read in super root block parsing
nilfs2: fix infinite loop in nilfs_clean_segments()
nilfs2: fix slab-out-of-bounds in nilfs_direct_propagate after truncation
Documentation: fix grammar in description of nilfs2 recovery code
nilfs2: handle corrupted checkpoint count gracefully during deletion
nilfs2: reject invalid block index in GC ioctl
|
||
|
|
0de672c7e1 |
hfs/hfsplus updates for v7.3
- hfsplus: validate extent record length before writing it back
- hfsplus: validate B-tree record offset table
- hfs: rework MDB locking scheme
- fs: hfsplus: remove redundant NULL check before kfree()
- hfs: port HFS+ b-tree bitmap corruption check
- hfs: don't re-dirty MDB buffers after a write failure
- hfsplus: fix error code when writing beyond volume capacity
- hfs: fix error code when writing beyond volume capacity
- hfsplus: validate thread record before delete key rebuild
- hfs: validate catalog CNIDs before instantiating inodes
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQT4wVoLCG92poNnMFAhI4xTh21NnQUCan+JtwAKCRAhI4xTh21N
ndwRAQCo1yRn8Dt1H1ecRH1aXFEceQ1IiDRyklA/0sdXE1iRcAD9Gh5mUvXKvkww
TYTKWgFlqBZTODeAhD5kV/Vqai0AAAQ=
=9ixe
-----END PGP SIGNATURE-----
Merge tag 'hfs-v7.3-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/vdubeyko/hfs
Pull HFS updates from Viacheslav Dubeyko:
"This contains several fixes in HFS/HFS+ of syzbot reported issues and
HFS/HFS+ fixes of xfstests failures.
- b-tree bitmap corruption check (Aditya Prakash Srivastava)
During b-tree open (hfs_btree_open()), the code verifies that the
allocation map bit for the tree header (node 0) is set. If not, it
indicates a corrupted map record/bitmap and mounts the volume as
read-only (SB_RDONLY) to prevent further damage.
- Validate catalog CNIDs before instantiating inodes (David
Maximiliano Hermitte)
The hfs_cat_find_brec() first resolves a catalog thread record by
CNID and then looks up the corresponding catalog record by
parent/name. On a corrupted filesystem image, the second lookup may
find a record whose CNID does not match the CNID that was
requested. Finally, corrupted catalog records are rejected.
- Validate B-tree record offset table (Jiaming Zhang)
A crafted HFS+ image can contain a corrupted B-tree node. The node
descriptor may contain a record count that does not fit in the
node, and record offsets may be unordered, unaligned, outside the
node, or point into the offset table itself. Validate num_recs
against the node size before walking the record offset table.
Reject record ranges that are unordered, unaligned, outside the
node, or overlapping the offset table. Reject invalid record
indexes before reading their offset entries, and avoid decrementing
an already-zero leaf_count.
- Refactoring of hfsplus_delete_cat() logic (Kyle Zeng).
The hfsplus_delete_cat() is called with str == NULL when the last
open reference to an unlinked HFS+ hardlink backing inode is
closed. In that case, the function finds the catalog thread by CNID
and rebuilds the catalog key from thread.nodeName. A corrupted
image can therefore provide an oversized thread name length and
make hfs_bnode_read() write past the catalog search-key allocation.
Read the CNID record through hfsplus_brec_read_cat(), which bounds
the record read to sizeof(hfsplus_cat_entry) and verifies that a
thread record's size exactly matches nodeName.length.
- Cleanup in KUnit test (Mohammad Shahid)
The kfree() safely handles NULL pointers, so the explicit NULL
check in free_mock_str_env() before calling kfree() is unnecessary.
The rest contain fixes of generic/564 xfstests' test-case failure
for the case of HFS+ file system, syzbot reported issue in
hfs_mdb_commit() and hfs_mdb_close() methods of HFS file system,
and reworking the MDB locking scheme in HFS file system"
* tag 'hfs-v7.3-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/vdubeyko/hfs:
hfsplus: validate extent record length before writing it back
hfsplus: validate B-tree record offset table
hfs: rework MDB locking scheme
fs: hfsplus: remove redundant NULL check before kfree()
hfs: port HFS+ b-tree bitmap corruption check
hfs: don't re-dirty MDB buffers after a write failure
hfsplus: fix error code when writing beyond volume capacity
hfs: fix error code when writing beyond volume capacity
hfsplus: validate thread record before delete key rebuild
hfs: validate catalog CNIDs before instantiating inodes
|
||
|
|
4bb187d6f3 |
gfs2 changes
- Don't cache unreferenced glocks: when a glock is no longer referenced (for example, because the inode it protects is evicted), it is now released as soon as possible instead of leaving it around until memory pressure or an unmount forces it out. For some workloads, this saves a lot of memory and speeds up unmounts significantly. - Harden gfs2_glock_hold() by making sure the caller holds a reference and fix a related race in checking for the liveliness of glocks between gdlm_bast() and gfs2_glock_cb(). -----BEGIN PGP SIGNATURE----- iQJIBAABCgAyFiEEJZs3krPW0xkhLMTc1b+f6wMTZToFAmqC7e8UHGFncnVlbmJh QHJlZGhhdC5jb20ACgkQ1b+f6wMTZTql+A/+OLEPtizpJ6k/uqk7+I63D0xYakK5 GMWCPPf5C9fernW57cF/p0TfRRDUKqKOrb+mKkJuPBMSfEZIldKOmYQx6U/kvXIF 6hdtRfAvVBjIs1aY+P/dliRXfzvO1HVamPsu7dx7NdTnozJz2tv/spNQ2cZV5tQD 2t6VovUzje+U7x7Qsz3EhN/po1aNBlXlzWtvF/r7uwAtiYfXaknJkr8cjo202w0Y fAQ5KRZA5EiN1Fc1d6V7ehYyzv31osmaQA9Bsf7NVlpnBPG1LyibYWzFF4zg1pDo 9JU4tcD9IpIALwYkGFFcG1qutjq0E2QKqeYgaIau94ezQnTY+q1zQQDiixyoHxHu 2AHMIcbUzEKHib+pYWtSy5GLgeTI59+hxFe9tOERhjHGDW8fYbqQTV969S84bYTm +Ar04VsbToMdjYSh5I+FPLQbKwfetKjDIlKSYeZzMOfGEqpJtoU9lB8WbvP/2LcQ c5hJfJcV7JWW9j4YZZIZuwzZv93CstBvFubKpktMw0x9utGc6a7M+f9eADYnd3JH l7yb+dyjUeYeIqEbALsfnxicuoiYfVKNVxh/zdz4TJEYDH1l/CyBIirLsSAVTAJl ruCT13akq5e+EXGOztcIXyU39l/ajJA0v58n9gzEzMakTwpyCTwx7WcooILf1aem P1QRnAoud8FoAYk= =U72j -----END PGP SIGNATURE----- Merge tag 'gfs2-for-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2 Pull gfs2 updates from Andreas Gruenbacher: - Don't cache unreferenced glocks: when a glock is no longer referenced (for example, because the inode it protects is evicted), it is now released as soon as possible instead of leaving it around until memory pressure or an unmount forces it out. For some workloads, this saves a lot of memory and speeds up unmounts significantly. - Harden gfs2_glock_hold() by making sure the caller holds a reference and fix a related race in checking for the liveliness of glocks between gdlm_bast() and gfs2_glock_cb(). * tag 'gfs2-for-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: gfs2: harden gfs2_glock_hold gfs2: Remove the glock lru list and shrinker gfs2: Skip dlm unlocks earlier gfs2: Don't cache unreferenced glocks gfs2: Enable automatic glock hash table shrinking |
||
|
|
cf07e82984 |
xfs: new patches for Linux 7.3
Signed-off-by: Carlos Maiolino <cem@kernel.org> -----BEGIN PGP SIGNATURE----- iJUEABMJAB0WIQSmtYVZ/MfVMGUq1GNcsMJ8RxYuYwUCaoK4XwAKCRBcsMJ8RxYu Y13uAX9yjOxdb5XA8FSEqu18n4oLn4XCC0DIIEzraKqdmL5X2jWzkwQsAEtGY75S QhDAqtcBgN1vjQyHfhQQsnFPk2M+0qEUevr53VNGF382UNtYISws2uoHWfV+gJ/M qkHyJJ9oPg== =IKKx -----END PGP SIGNATURE----- Merge tag 'xfs-merge-7.3' of git://git.kernel.org:/pub/scm/fs/xfs/xfs-linux Pull xfs updates from Carlos Maiolino: "There are no big standing out features on this window, so this mostly consists on bug fixes and code refactoring. The only user visible change that stands out is the support for FALLOC_FL_WRITE_ZEROES added to this" * tag 'xfs-merge-7.3' of git://git.kernel.org:/pub/scm/fs/xfs/xfs-linux: (23 commits) xfs: validate attr entry pointer before field access xfs: check split_sectors validity before bio_split call xfs: use file target for post-log fsync fallback flush xfs: restore nofs context unconditionally in xfs_trans_roll xfs: add lockless xfs_buf_readahead_map fast path xfs: move buffer locking out of xfs_find_get_buf xfs: merge xfs_buf_reverify into xfs_buf_read_map xfs: use goto based error unwinding in xfs_buf_read_map xfs: don't reverify buffers in xfs_buf_readahead_map xfs: use WRITE_ONCE to update b_flags xfs: hide b_flags manipulation from code outside of xfs_buf.c xfs: remove _XBF_LOGRECOVERY xfs: remove spurious XBF_DONE clearing on readahead validation failure xfs: split out a lower-level xfs_buf_get_map helper from xfs_find_get_buf xfs: consolidate buffer locking in xfs_buf_get_map xfs: don't get a pag reference in xfs_buf_get_map xfs: use kmalloc_objs() instead of kmalloc() in xfs_da_grow_inode_int xfs: mark internal metadir file creation helpers static xfs: create rtgroup metadir inodes using xfs_metadir_create_file xfs: create quota metadir inodes using xfs_metadir_create_file ... |
||
|
|
0a1703eba2 |
f2fs: fix to avoid pinfile fragment on fragment:{block, segment} mode
pinfile fallocate() conflicts w/ mode=fragment:{block,segment} mount option,
result in fragment blocks in pinfile, it violate semantics of pinfile
introduced in commit
|
||
|
|
6da62bbde4 |
f2fs: cleanup w/ f2fs_need_rand_{blk, seg, seg_blk}
No logic changes. Signed-off-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> |
||
|
|
5d49025a4e |
f2fs: fix to shrink gc_lock coverage in f2fs_gc_range()
In f2fs_allocate_pinning_section(), we will hold gc_lock before calling f2fs_gc_range() to migrate section in conventional zone, we may suffer worse case because we may need to traverse and migrate multiple sections if we failed to move blocks in section due to lot of reasons: ENOMEM, fail to migrate block of pinfile, racing on i_gc_rwsem. To avoid hold gc_lock for long time to block checkpoint, let's hold the lock and only try to migrate one section. Cc: Daeho Jeong <daehojeong@google.com> Signed-off-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> |
||
|
|
fa487f56ef |
f2fs: fix to reclaim space in f2fs_allocate_pinning_section()
It needs to trigger checkpoint to free space reclaimed by f2fs_gc_range(),
otherwise, fallocate() on pinfile will fail easily even there is slash
space in conventional zone.
[Testcase]
nullblk_create.sh 512 2 1024 1024
mkfs.f2fs /dev/nullb0 -f -m
mount /dev/nullb0 /mnt/f2fs/
touch /mnt/f2fs/pinfile
f2fs_io pinfile set /mnt/f2fs/pinfile
mkdir /mnt/f2fs/dir/
for((i=0;i<3934;i++)) do { dd if=/dev/zero of=/mnt/f2fs/dir/$i bs=1M count=1;} done
sync
for((i=0;i<3934;i+=2)) do { rm /mnt/f2fs/dir/$i;} done
for((i=0;i<1950;i++)) do { rm /mnt/f2fs/dir/$i;} done
sync
f2fs_io fallocate 0 0 $((1024*1024*1024)) /mnt/f2fs/pinfile
sync
stat /mnt/f2fs/pinfile
f2fs_io fiemap 0 $((1024*1024*1024)) /mnt/f2fs/pinfile
[Before]
fallocate failed: Resource temporarily unavailable
File: /mnt/f2fs/pinfile
Size: 109051904 Blocks: 213208 IO Block: 4096 regular file
Device: 250,0 Inode: 4 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2026-08-12 20:04:02.264000000 +0800
Modify: 2026-08-12 20:04:26.784000000 +0800
Change: 2026-08-12 20:04:26.784000000 +0800
Birth: -
root@localhost:~#
root@localhost:~#
root@localhost:~#
root@localhost:~# f2fs_io fiemap 0 $((1024*1024*1024)) /mnt/f2fs/pinfile
Fiemap: offset = 0 len = 1073741824
logical addr. physical addr. length flags
0 0000000000000000 0000000002e00000 0000000000200000 00001000
1 0000000000200000 000000002dc00000 0000000000400000 00001000
2 0000000000600000 000000002e400000 0000000000600000 00001000
3 0000000000c00000 000000007a400000 0000000005c00000 00001001
[After]
File: /mnt/f2fs/pinfile
Size: 1073741824 Blocks: 2099216 IO Block: 4096 regular file
Device: 250,0 Inode: 4 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2026-08-12 19:47:49.428000000 +0800
Modify: 2026-08-12 19:49:06.808000000 +0800
Change: 2026-08-12 19:49:06.808000000 +0800
Birth: -
Fiemap: offset = 0 len = 1073741824
logical addr. physical addr. length flags
0 0000000000000000 0000000002e00000 0000000000200000 00001000
1 0000000000200000 000000003aa00000 0000000000400000 00001000
2 0000000000600000 000000003b400000 0000000000200000 00001000
3 0000000000800000 000000007a200000 0000000005e00000 00001000
4 0000000006600000 0000000002800000 0000000000200000 00001000
5 0000000006800000 0000000003200000 0000000000400000 00001000
6 0000000006c00000 0000000003000000 0000000000200000 00001000
7 0000000006e00000 0000000003600000 0000000037200000 00001000
8 000000003e000000 000000003b200000 0000000000200000 00001000
9 000000003e200000 000000003a800000 0000000000200000 00001000
10 000000003e400000 000000003ae00000 0000000000400000 00001000
11 000000003e800000 000000003b600000 0000000001800000 00001001
Cc: stable@kernel.org
Fixes:
|
||
|
|
ff68e5f557 |
vfs-7.3-rc1.sync
Please consider pulling these changes from the signed vfs-7.3-rc1.sync tag.
Thanks!
Christian
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJQAKCRCRxhvAZXjc
olUCAQDLfbikQzGtIXXgmUh1HbJhxycYDWvdh2ug9teN4IsdMAD+IcpnzVIN+AdF
PZWewxJEzzR1P1jL2aE8XDUTI4boCw4=
=SgO+
-----END PGP SIGNATURE-----
Merge tag 'vfs-7.3-rc1.sync' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs writeback updates from Christian Brauner:
"This makes sync_inode_metadata() and writeback_single_inode() persist
not only the inode but all metadata associated with it.
A new .sync_inode_metadata superblock operation is called from
__writeback_single_inode(). Alongside it a new I_METADATA_WRITEBACK
state flag is added.
Filesystems no longer need their own mmb_fsync() implementations and
can just use simple_fsync(). All metadata is now written for IS_SYNC
and IS_DIRSYNC inodes. Races where several fsyncs raced and mmb_sync()
could return before all buffers were really persisted are fixed since
I_SYNC now serializes properly.
The I_METADATA_WRITEBACK scheme also fixes the case where a
WB_SYNC_NONE writeback landing between write(2) and fsync(2) left
fsync(2) failing to persist the inode. That problem is not specific to
filesystems using the generic metadata bh tracking, and the ones that
do not are left alone.
ext2, udf, bfs, minix, fat and ext4 in nojournal mode have their data
integrity writeout fixed and are converted. affs drops metadata bh
tracking and mmb_fsync() is removed.
A few other fixes came out of this:
- a UAF in mark_buffer_write_io_error()
- missed inode writeback when racing with __writeback_single_inode()
- ext4 allocating the mapping_metadata_bhs struct on demand
- three fat fixes: a lost inode update in do_msdos_rename() with
DIRSYNC, inode buffer write errors not propagating out of
fat_sync_inode_metadata() and directory entries not being
persisted on fsync(2) of the root directory"
* tag 'vfs-7.3-rc1.sync' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (24 commits)
writeback: Export __inode_attach_wb()
fat: Fix persisting directory entries on fsync(2) of the root directory
fat: Propagate inode buffer write errors from fat_sync_inode_metadata()
fat: Fix lost inode update in do_msdos_rename() with DIRSYNC
vfs: Remove mmb_fsync()
fat: Replace fat_sync_inode() with sync_inode_metadata()
fat: Fix missed inode writeback during fsync(2)
ext4: Fix data integrity writeout issues in nojournal mode
minix: Fix data integrity writeout issues
bfs: Fix data integrity writeout issues
udf: Fold udf_update_inode() into udf_write_inode()
udf: Use sync_inode_metadata() in udf_evict_inode()
udf: Drop udf_sync_inode()
udf: Use sync_inode_metadata() to writeout IS_SYNC inode
udf: Fix data integrity writeout issues
ext2: Fix data integrity writeout issues
ext2: Avoid unnecessary inode buffer writeback for sync(2)
ext2: Drop __ext2_write_inode()
ext2: Fix lost inode updates for IS_SYNC inodes
fs: Provide way for filesystem to wait for metadata writeback
...
|
||
|
|
1781f0b3d7 |
vfs-7.3-rc1.super
Please consider pulling these changes from the signed vfs-7.3-rc1.super tag. Thanks! Christian -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJQAKCRCRxhvAZXjc oroBAP40BufiChnC6I9Ev79QWF+Pfri1r/3AR4xXRG4HkXQaYQD/YE+Ria3+Bt35 +tWU66cYlQ/+9LfU8DJ3KXm7jPUBiQA= =hXLH -----END PGP SIGNATURE----- Merge tag 'vfs-7.3-rc1.super' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs superblock updates from Christian Brauner: - Make it possible to share a block device between multiple filesystems. erofs can mount read-only blob devices shared between many superblocks, but because we only tracked a single superblock a freeze, thaw, removal or sync on such a device was never propagated to all the superblocks using it, and there was no way to find them. Add an efficient table to lookup all superblocks using a given block device. - A bunch of pre-existing fixes fell out of this work: A block-device freeze racing a btrfs device change could leave the whole filesystem stuck frozen. A bdev_freeze() issued by "dmsetup suspend" or an LVM snapshot resolves that holder to freeze the filesystem. and bdev_thaw() resolves it again to thaw. A freeze landing while btrfs is adding, removing or replacing a device freezes the filesystem. The membership change then drops that link. So the matching thaw could no longer find the superblock. Forbid freezing a device for the duration of a membership change, modelled on deny_write_access()/allow_write_access(). * tag 'vfs-7.3-rc1.super' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (24 commits) super: fix dying superblock warning messages block: reject block device inodes with i_rdev == 0 in lookup_bdev() selftests/filesystems: add ustat() coverage fs: look up the superblock via the device table in user_get_super() super: make fs_holder_ops private f2fs: open via dedicated fs bdev helpers erofs: open via dedicated fs bdev helpers fs: tolerate per-superblock freeze errors on shared devices fs: look up superblocks via the device table in fs_holder_ops ext4: open via dedicated fs bdev helpers btrfs: open via dedicated fs bdev helpers xfs: port to fs_bdev_file_open_by_path() fs: add dedicated block device open helpers for filesystems fs: maintain a global device-to-superblock table ocfs2: don't reset s_dev on dismount ext4: use anonymous devices for KUnit test superblocks fs, block: move blk_mode_t and fop_flags_t into <linux/types.h> super: take lock after last reference count super: convert s_count to refcount_t s_passive btrfs: deny freezing devices undergoing a replace ... |
||
|
|
aaed66fadb |
vfs-7.3-rc1.ovl
Please consider pulling these changes from the signed vfs-7.3-rc1.ovl tag. Thanks! Christian -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJQAKCRCRxhvAZXjc ok/9AQDpiRYIoLwnUa7URD92AQXBRQeSYFqicAqDqP3NpCUMwQD+IcmA1EtkfmaG ROdhiUJWe8TV5Ci1qNPXzoy1XRVhNQU= =xOj4 -----END PGP SIGNATURE----- Merge tag 'vfs-7.3-rc1.ovl' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull overlayfs updates from Christian Brauner: "This lets the merged overlayfs mount itself be idmapped through mount_setattr(MOUNT_ATTR_IDMAP), in addition to the already supported idmapped lower and upper layers. The same overlay tree can then be exposed under a different ownership view. Overlayfs already normalizes every underlying id through the relevant layer idmap when ovl_copyattr() copies attributes into the overlay inode. So the overlay inode's i_uid and i_gid are overlay-final ids. The overlay mount idmap composes on top of that and is applied at the overlay-inode boundary only while the underlying layers keep being accessed with the mounter's credentials through their own (possibly idmapped) mounts. So this only changes how the caller sees the overlay inode and never widens the mounter's access to the layers. The second, mounter-credential check in ovl_permission() against the real inode stays on the layer idmap. Most paths need no change because the VFS applies the mount idmap to the overlay inode before overlayfs runs or after it returns at the syscall boundary. Overlayfs only has to change where it bypasses the generic path. This also included is a fix for a double end_creating() on the overlayfs casefold-mismatch path" * tag 'vfs-7.3-rc1.ovl' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: ovl: fix double end_creating() on the casefold-mismatch path ovl: document security.capability idmapping on the xattr forward paths selftests/filesystems/overlayfs: test idmapped overlay mounts selftests/filesystems/overlayfs: fix set_layers_via_fds link error docs: document idmapped overlay mounts ovl: allow idmapping overlay mounts ovl: handle idmapped mounts in ovl_set_acl() ovl: handle idmapped mounts in ovl_getattr() ovl: handle idmapped mounts in ovl_setattr() ovl: handle idmapped mounts in ovl_permission() ovl: handle idmapped mounts in ovl_create_object() and ovl_tmpfile() |
||
|
|
55668d04e3 |
vfs-7.3-rc1.netfs
Please consider pulling these changes from the signed vfs-7.3-rc1.netfs tag. Thanks! Christian -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJQAKCRCRxhvAZXjc oq5VAPwLHEyDBJUM581Nsj9O7NnkSRhffjp4//Cp2jHRYkaR4wEAiceqF+rONVWK VYCyLEDSU5TPP9EeON95qSzq0khbswo= =kcGi -----END PGP SIGNATURE----- Merge tag 'vfs-7.3-rc1.netfs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull cachefiles ondemand removal from Christian Brauner: "This sunsets cachefiles ondemand mode. It was an effort to make fscache usable as a kernel cache for lazy pulling. EROFS over fscache was its only in-tree user. fscache has since become netfslib-oriented while EROFS never acts as a network filesystem and EROFS over fscache has been removed. So this cleans up the netfs, fscache and cachefiles side as well" * tag 'vfs-7.3-rc1.netfs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: cachefiles,netfs: sunset ondemand mode |
||
|
|
c3d6d6dde3 |
vfs-7.3-rc1.mount
Please consider pulling these changes from the signed vfs-7.3-rc1.mount tag. Thanks! Christian -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJQAKCRCRxhvAZXjc omDqAP9BOedYydQiJhviQggsX5IFfDfCa1semGokHPOsW9WKHwD+PJBHVLvvP/uU TmzBuX9zkDzPGEDcT7arcXjzKu8gLgY= =d1MF -----END PGP SIGNATURE----- Merge tag 'vfs-7.3-rc1.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull mount updates from Christian Brauner: - Make the legacy mount API notify pollers of propagation changes. Changing propagation via change_mnt_propagation() or with MOVE_MOUNT_SET_GROUP update the propagation relationship of the target mount. But unlike mount_setattr() neither path touched the affected mount namespace. So pollers of /proc/<pid>/mountinfo were never woken. - Also remove a redundant panic() in mnt_init() * tag 'vfs-7.3-rc1.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: mount: remove redundant panic() in mnt_init() fs/namespace: notify pollers of legacy propagation changes |
||
|
|
1c3e8cef79 |
vfs-7.3-rc1.misc
Please consider pulling these changes from the signed vfs-7.3-rc1.misc tag.
Thanks!
Christian
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJQAKCRCRxhvAZXjc
otI6AQCIwshv02UI9fmbTC9pFr8b+v/9IWQwdVULaH61HXgICQD7BE/CktL8nfRs
zCzGS6kBdWgiOA6bdVpgGGLqiMRnQgo=
=Kc+G
-----END PGP SIGNATURE-----
Merge tag 'vfs-7.3-rc1.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull misc vfs updates from Christian Brauner:
"Bigger cleanups:
- The lockref dead-count handling is tidied up.
The open-coded check for a count below zero as the dead marker
relies on information the caller should not have.
- make put_mnt_ns() leave mounts connected. Destroying a mount
namespace disconnected its mounts from their mount points. So a
file descriptor still open on the parent of a mount point could be
used to peek under it.
Locked mounts were already kept connected to prevent exactly that.
But a mount is only locked when its tree is copied across a user
namespace boundary. So a mount namespace set up by a privileged
component had no locked mounts and its mounts were disconnected.
Passing UMOUNT_CONNECTED keeps every mount connected and prevents
that bug.
- vfs_prepare_mode() passes S_IFDIR for directories. I meant to fix
that ago but didn't get to it. So now someone finally did it.
This kills the exception where the mode could be 0 when a directory
was created whereas every other creation operation passed it
explicitly already.
- move long delayed work for ufs, jffs2, hfsplus, hfs and affs from
the per-cpu system_long_wq to the new unbound system_dfl_long_wq.
None of that work relies on per-cpu state and the work item is
enqueued with queue_delayed_work() whose timer is global anyway. So
it may as well benefit from scheduler task placement.
Smaller fixes and cleanups:
- unlock_buffer() and journal_end_buffer_io_sync() use
clear_and_wake_up_bit()
- the pipe page pools are unified into a single per-pipe pool and the
extra wake_up(rd_wait) is limited to EPOLLET consumers
- eventpoll now computes its timer slack lazily in ep_poll()
- shrink_dcache_for_umount() keeps making progress on busy roots
- excess xarray nodes are freed in clear_inode()
- romfs detects hard link cycles
- the user path of nested backing files is fixed
- pidfd holds exec_update_lock around the namespace ioctl
- non-memcg-aware nr_cached_objects is skipped during memcg slab
shrink
- iomap_write_iter() always returns status
- mangle_path() is renamed to seq_mangle_path()
- inode timestamp accessors are annotated
- new regression test for pipe->poll_usage.
- a few documentation, kernel-doc and selftest fixes"
* tag 'vfs-7.3-rc1.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (67 commits)
selftests/namespaces: Fix racy pipe handshake in timens and pidns_separate
selftests/epoll: add a regression test for pipe->poll_usage
pipe: only enable the extra wake_up(rd_wait) for EPOLLET consumers
pidfd: hold exec_update_lock around namespace ioctl
fs: fix user path of nested backing files
fs: remove stale inode_insert5() kernel-doc parameter
fs: fix switch/case indentation in sysfs() syscall
fs: document semantics of kstat::{uid,gid} fields
dcache: keep shrink_dcache_for_umount() making progress on busy roots
seq_file: rename mangle_path to seq_mangle_path
nstree: add/fix struct ns_id_req kernel-doc member fields
dcache: use lockref routines for dead count checks
lockref: tidy up dead count handling
initramfs: fix typo in reserve_initrd_mem comment
fs/pipe: unify the page pools into a single per-pipe pool
fs: annotate inode timestamp accessors
eventpoll: compute timer slack lazily in ep_poll()
selftests/filesystems: add mntns cleanup test
put_mnt_ns(): leave mounts connected
affs: Move long delayed work on system_dfl_long_wq
...
|
||
|
|
ab5ed08f2d |
vfs-7.3-rc1.lookup
Please consider pulling these changes from the signed vfs-7.3-rc1.lookup tag. Thanks! Christian -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJQAKCRCRxhvAZXjc ouj6AQCnBHstCt5RRimywLYU+eTmdKe203zRQYxXpwlYOAzm7wEAm1mIC7/Of6bD jkiJilcPDcyYcJsqwBw/Vcz5HR+v8wo= =TX6K -----END PGP SIGNATURE----- Merge tag 'vfs-7.3-rc1.lookup' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs lookup updates from Christian Brauner: "This refactors lookup_open() and adds vfs_lookup_open() for nfsd. mnt_want_write() and parent locking are moved into lookup_open() itself. audit_inode_child() is also now called in lookup_open() on failure. That is the calling convention in vfs_create() and vfs_mkdir(), but lookup_open() made no such call when atomic_open() should have created a file and did not. And neither did the regular ->create() path fwiw. This also contains work to remove the unneeded excl argument from the ->create() inode op" * tag 'vfs-7.3-rc1.lookup' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: fs/namei.c: fix coding style in atomic_open() and lookup_open() fs/namei.c: fix kerneldoc of atomic_open() and vfs_lookup_open() fs/namei.c: update stale comments in lookup_open() Remove excl arg to ->create inode_operation fs/namei.c: update kerneldoc of atomic_open() vfs: call audit_inode_child() in lookup_open() on failure vfs: move create error && negative dentry case in lookup_open() up VFS: add vfs_lookup_open() for nfsd VFS: move delegated_inode retry loop into lookup_open() VFS: move mnt_want_write() and locking into lookup_open() |
||
|
|
fff0150b02 |
vfs-7.3-rc1.kthread
Please consider pulling these changes from the signed vfs-7.3-rc1.kthread tag. Thanks! Christian -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJQAKCRCRxhvAZXjc ohHuAQCFeGhxqsb44KhuJaWXewiXbefr6eg31lXmxgSfg0DILAD/Tw/WmpiUbX5M H+/jh6NmLKnQ/ADjlWFRy3R1K1Il3w4= =jwPP -----END PGP SIGNATURE----- Merge tag 'vfs-7.3-rc1.kthread' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull kthread vfs updates from Christian Brauner: "This stops kernel threads from sharing filesystem state with userspace. This work is about 3 cycles old and has been in -next for about that time. When the kernel boots init_task creates PID 1 and then kthreadd. From that point every kthread and PID 1 share the same fs_struct. That is why pivot_root() has to rewrite the fs_struct of all kthreads. The rewriting exists so that kthreads can use init's filesystem state when they want to. It also means userspace can move the ground out from under the kernel. PID 1 now gets a completely separate fs_struct. All kthreads are anchored in a private SB_KERNMOUNT instance of nullfs that cannot be mounted on and cannot be used to follow other mounts. Userspace init can no longer affect kthread filesystem state and kthreads can no longer affect userspace fs state without explicit opting in to that. Path lookup from a kthread now fails by default. It makes it deliberately hard to offload security sensitive operations into init's filesystem state from a kthread. Places that legitimately need to look something up there opt in through the new scoped_with_init_fs() which temporarily overrides the caller's fs_struct with init's. usermodehelpers remain the only kernel tasks that genuinely share init's filesystem state, since they execute random binaries in the root filesystem (excellent...). The visible result is that /proc/2/root is a nullfs with an empty mountinfo while /proc/1/root is the real root" * tag 'vfs-7.3-rc1.kthread' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (26 commits) initramfs_test: use test init/exit hooks to override init fs fs: stop rewriting paths for PF_EXITING | PF_DUMPCORE fs: stop rewriting kthread fs structs fs: start all kthreads in nullfs nullfs: make nullfs multi-instance devtmpfs: create private mount namespace fs: add umh argument to struct kernel_clone_args fs: stop sharing fs_struct between init_task and pid 1 af_unix: use scoped_with_init_fs() for coredump socket lookup initramfs: use scoped_with_init_fs() for rootfs unpacking pnfs/blocklayout: use scoped_with_init_fs() for SCSI device lookup ksmbd: use scoped_with_init_fs() for VFS path operations ksmbd: use scoped_with_init_fs() for filesystem info path lookup ksmbd: use scoped_with_init_fs() for share path resolution fs: use scoped_with_init_fs() for kernel_read_file_from_path_initns() coredump: use scoped_with_init_fs() for coredump path resolution btrfs: use scoped_with_init_fs() for update_dev_time() scsi: target: use scoped_with_init_fs() for APTPL metadata scsi: target: use scoped_with_init_fs() for ALUA metadata crypto: ccp: use scoped_with_init_fs() for SEV file access ... |
||
|
|
de03b17ec0 |
vfs-7.3-rc1.kfunc
Please consider pulling these changes from the signed vfs-7.3-rc1.kfunc tag. Thanks! Christian -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJQAKCRCRxhvAZXjc oqBnAQDzCTHIa0wColluZLaFVuL4pvipQzC7tjUUQCwPmy85EwEA2cyeguEkNYJZ SK3m4z8kfuZjO2tEOig+XCkmtVrSMQQ= =6gwq -----END PGP SIGNATURE----- Merge tag 'vfs-7.3-rc1.kfunc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs bpf access updates from Christian Brauner: "This adds a bpf_sock_read_xattr() kfunc so a BPF LSM program can read a user.* extended attribute from a socket's sockfs inode locklessly. userspace already uses user.* xattrs on sockets to implement socket rate limiting and to tag sockets for other purposes such as a varlink registry. There has been no efficient way for a BPF program to read those labels back. With this a listening socket marked from userspace with fsetxattr() can be read back during bind or connect and acted upon on the connecting socket. That lets userspace mark sockets and later rediscover them or implement policy on them" * tag 'vfs-7.3-rc1.kfunc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: selftests/bpf: Add test for bpf_sock_read_xattr() kfunc fs: Add bpf_sock_read_xattr() kfunc to read socket xattrs |
||
|
|
9ea8d6197d |
vfs-7.3-rc1.iomap
Please consider pulling these changes from the signed vfs-7.3-rc1.iomap tag.
Thanks!
Christian
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJQAKCRCRxhvAZXjc
oqOjAP9eZsO4M7OQpTKPgg3Sq2O9QCVgXBy4SVFba7DrbZHLZAEA/NWE+4udJzeL
j1Xb2VAyMc4S+Ze/O8sMml5Dyh4V5wE=
=34r1
-----END PGP SIGNATURE-----
Merge tag 'vfs-7.3-rc1.iomap' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull iomap updates from Christian Brauner:
"The bulk of this is the conversion of iomap to a single ->iomap_next()
callback and thus finishing the move to an iterator model.
Every iomap operation drove its iteration through a struct iomap_ops
holding ->iomap_begin() and ->iomap_end(). iomap_iter() only ever sees
those as pointers. That means every step of every iteration is an
indirect call.
This collapses both into one ->iomap_next() callback that finishes the
previous mapping and produces the next one. This lets callers inline
the iteration loop and pass its ->iomap_next() as a compile time
constant. That means the compiler can turn it into a direct and hence
inlineable call.
This also allows future callers to express custom logic to drive the
iteration forward better. xfs, btrfs, ext4, ext2, erofs, f2fs, gfs2,
hpfs, fuse, exfat, zonefs, ntfs, ntfs3 and the block device mapping
are all converted. No functional changes are intended.
This also adds a simple direct I/O path for small reads. On Gen5 NVMe
the __iomap_dio_rw() dominates 4K random reads. The same single-core
io_uring poll mode workload reaches ~3.2M IOPS against the raw block
device but only ~1.92M through ext4 or XFS.
__iomap_dio_rw(), iomap_iter(), iomap_dio_bio_iter() and kfree() were
at the top of the profile. The new path is very lightweight if no
special behavior is requested. The bio comes from a dedicated bioset
and laid out so the whole request is a single cacheline aligned
allocation. Completion runs inline.
That takes ext4 from 1.92M to 2.19M IOPS in the original workload. fio
shows around:
- 4% at libaio queue depths of 64 and up
- around 5% for io_uring
- up to 10% for io_uring poll mode at depth 256
on both ext4 and xfs.
A few other patches:
- iomap_folio_mark_uptodate() lets a filesystem that writes into the
page cache outside the iomap read and write paths keep iomap's
internal uptodate bitmap in sync, which fuse needs for
server-pushed notify stores before it can enable large folios;
- two fixes for iomap_bio_read_folio_range_sync(): a potential crash
when device integrity behavior is changed and a missing
bio_uninit().
- a folio batch release fix on iomap callback failures
- FGP_NOFS is dropped from iomap_get_folio()
- documentation fix"
* tag 'vfs-7.3-rc1.iomap' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (29 commits)
iomap: iomap_bio_read_folio_range_sync is missing a call to bio_uninit
iomap: don't free integrity payload that doesn't exist
docs: fix grammatical error in iomap docs
exfat: convert iomap ops to ->iomap_next()
fuse: convert iomap ops to ->iomap_next()
hpfs: convert iomap ops to ->iomap_next()
gfs2: convert iomap ops to ->iomap_next()
f2fs: convert iomap ops to ->iomap_next()
block: convert iomap ops to ->iomap_next()
ext2: convert iomap ops to ->iomap_next()
zonefs: convert iomap ops to ->iomap_next()
erofs: convert iomap ops to ->iomap_next()
ext4: convert iomap ops to ->iomap_next()
ntfs: convert iomap ops to ->iomap_next()
ntfs3: convert iomap ops to ->iomap_next()
btrfs: convert iomap ops to ->iomap_next()
xfs: convert iomap ops to ->iomap_next()
iomap: add ->iomap_next()
iomap: use GFP_NOWAIT when application for iomap_dio_simple allocations
iomap: decouple simple direct I/O reads from iomap_dio_rw
...
|
||
|
|
3d1f952677 |
vfs-7.3-rc1.fat
Please consider pulling these changes from the signed vfs-7.3-rc1.fat tag. Thanks! Christian -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJAAKCRCRxhvAZXjc onKkAP40wNdwV6l2ve+dioDeEAd7L8hBANbh6X6p7s8s1WUaQAEAtdq8PsA2UqBy RjS/Mj5X+MTttydrrp3A7FQdhf5/lwQ= =DHKe -----END PGP SIGNATURE----- Merge tag 'vfs-7.3-rc1.fat' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull FAT update from Christian Brauner: "This rejects names longer than NAME_MAX in msdos_format_name(). The VFS only enforces PATH_MAX rather than the length of an individual component. open() on such a path component reported success for a name far longer than NAME_MAX" * tag 'vfs-7.3-rc1.fat' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: fat: reject name longer than NAME_MAX in msdos_format_name() |
||
|
|
cd051cfe1e |
vfs-7.3-rc1.failfs
Please consider pulling these changes from the signed vfs-7.3-rc1.failfs tag. Thanks! Christian -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJAAKCRCRxhvAZXjc ouz+AQCXKHb1Ay9ra1RG+dGu8mCpVZLebMt/+VO0/beMCqiqWAD8ChgvsFqObmr5 8vLKOnzsSMeglRYGPL81h3xnaILRIQk= =0qwg -----END PGP SIGNATURE----- Merge tag 'vfs-7.3-rc1.failfs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull failfs filesystem from Christian Brauner: "Add failfs and expose a FD_FAILFS_ROOT sentinel. This allows userspace to shed their filesystem state completely. A process with its root or working directory in failfs must anchor every path lookup at an explicit file descriptor. Absolute paths, absolute symlinks and AT_FDCWD-relative lookups simply fail. Failfs is the counterpart to nullfs. nullfs says adds a permanently empty, immutable directory whose lookups fail with ENOENT but which can be opened, read, stat'd and mounted upon. Failfs on the other hand fails every operation. The root cannot be opened at all. A single instance is mounted during early boot via kern_mount(), which makes it logically distinct from every mount namespace. This is accompanied by a new fchroot() system call which makes chrooting via a file descriptor a first class concept. It's possible to chroot into failfs as an unprivileged user provided the task has no new privileges set" * tag 'vfs-7.3-rc1.failfs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: Documentation: add failfs documentation selftests/filesystems: add failfs selftests arch: hookup fchroot() system call fs: support FD_FAILFS_ROOT in fchroot() fs: add fchroot() fs: support FD_FAILFS_ROOT in fchdir() fs: add failfs |
||
|
|
10f307e525 |
nfs: fix ENXIO on O_CREAT open of existing symlink over NFSv3
When open(2) is called with O_CREAT on a path that already exists as a
symlink, over an NFSv3 mount with a cold dcache, the kernel returns
ENXIO instead of following the symlink to its target.
Reproducer script (MNT is an NFSv3 mount, kernel is 7.1-rc6):
MNT=/mnt/export
ln -sf /tmp/target $MNT/mylink
echo 3 | sudo tee /proc/sys/vm/drop_caches # cold dcache
python3 - <<'EOF'
import os
fd = os.open('/mnt/export/mylink', os.O_WRONLY | os.O_CREAT | os.O_APPEND, 0o666)
os.close(fd)
EOF
Expected: success (follow symlink, open target)
Actual: OSError: [Errno 6] No such device or address
The bug does not trigger when the dcache is warm (e.g. after a prior
stat(2)), because lookup_open() then finds a positive dentry and skips
atomic_open entirely, leaving symlink resolution to the VFS.
Root cause:
nfs_atomic_open_v23(), registered as inode->i_op->atomic_open for
NFSv3, handles O_CREAT by sending a CREATE UNCHECKED RPC. As
implemented in nfsd3_create_file() (fs/nfsd/nfs3proc.c) and as required
by RFC 1813 (3.3.8), when the name already exists as a non-regular file
the server returns NFS3_OK with the existing object's file handle rather
than NFS3ERR_EXIST causing nfs_do_create() to return 0 with the
dentry now pointing to a symlink.
The code then unconditionally calls finish_open(), which dispatches
through inode->i_fop->open(). Symlink inodes never have i_fop set — the
VFS initialises it to &no_open_fops because POSIX requires open(2) to
follow symlinks, never open them directly. no_open() returns -ENXIO.
Fix:
After nfs_do_create() succeeds, verify the returned inode is a regular
file before calling finish_open(). If the object is not regular, return
finish_no_open(file, NULL) so the VFS follows the symlink through the
normal open path. NULL is passed because nfs_do_create() instantiates
the inode on the dentry already owned by the caller; passing dentry back
would cause atomic_open() to dput() it a second time.
!S_ISREG() is used rather than S_ISLNK() to cover any other non-regular
types a server might return.
Changes in v2:
- Pass NULL to finish_no_open() per Trond's feedback.
Fixes:
|
||
|
|
468e458ffd |
NFSv4: Fix incorrect argument passed to nfs4_delete_lease() in nfs4_add_lease()
When nfs4_add_lease() races with a delegation return, it calls
nfs4_delete_lease() to clean up. Previously, it passed priv,
which can legitimately be NULL. Passing a NULL priv eventually
leads to a NULL pointer dereference in generic_setlease().
Fixes:
|
||
|
|
4c7fc129db |
lockd: fix NULL dereference on lockowner allocation failure
nlmclnt_locks_init_private() installs NLM file lock operations even when
nlmclnt_find_lockowner() fails to allocate a lockowner. nlmclnt_proc()
then returns -ENOMEM, but the VFS still tears down the partially
initialized file_lock and calls locks_release_private().
That invokes nlmclnt_locks_release_private(), which dereferences
fl->fl_u.nfs_fl.owner and crashes because the owner was never installed.
Clear fl_ops before attempting to initialize the NLM private state, and
install the NLM lock operations only after a lockowner has been allocated
successfully.
Fixes:
|
||
|
|
2092f5b38f |
NFS: fix delegation_hash_table leak when nfs4_server_common_setup() fails
nfs4_server_common_setup() allocates server->delegation_hash_table
first, but server->destroy - the only path that frees the table via
nfs4_destroy_server() - is not assigned until the very end of the
function. If any intermediate step fails (the is_ds_only_client()
check, nfs4_init_session(), nfs4_get_rootfh(), or nfs_probe_server()),
the function returns with server->destroy still NULL, so the caller's
nfs_free_server() skips the destroy callback and the hash table is
leaked (4 KiB per attempt with the default delegation watermark).
This is trivially reachable from userspace: every failed NFSv4 mount
leaks one allocation. A client that persistently retries a mount that
cannot succeed leaks kernel memory without bound. Observed in
production where a Longhorn backup poller retried mount.nfs4 against
an NFSv3-only server roughly 10 times per second, leaking ~3.4 GiB of
unreclaimable slab (kmalloc-rnd-13-4k) per day; the node accumulated
12 GiB of leaked slab before the source was identified via the
kmem:kmalloc tracepoint (call_site=nfs4_delegation_hash_alloc).
Reproducer:
# server exports NFSv3 only (or export path absent for v4)
while :; do mount -t nfs4 <server>:/missing /mnt; done
# watch SUnreclaim in /proc/meminfo grow 4 KiB per iteration
Free the table on the error paths between the allocation and the
assignment of server->destroy.
Fixes:
|
||
|
|
92a885576f |
NFSv4/flexfiles: support loosely coupled data servers
A flexfiles storage device is tightly coupled to the MDS only when the
decoded ds_versions[0].tightly_coupled flag is set (RFC 8435, sections
2.3 and 4.1). The client currently ignores that flag and treats every
data server as tightly coupled, which breaks I/O to loosely coupled DSes.
Two things force that assumption on an NFSv4.1+ DS:
1) nfs4_set_ds_client() always sets NFS_CS_PNFS on the new client, so
EXCHANGE_ID is sent with EXCHGID4_FLAG_USE_PNFS_DS.
2) nfs4_init_ds_session() then calls is_ds_client() and returns -ENODEV
if the reply does not carry EXCHGID4_FLAG_USE_PNFS_DS.
A loosely coupled DS is just a normal NFS server and does not act in the
pNFS DS role, so the client must not require it to advertise that role.
Thread the ds_versions[0].tightly_coupled flag from the flexfiles driver
down to the DS connect path. When it is false, skip both the NFS_CS_PNFS
flag and the is_ds_client() check. The file layout driver always passes
true because NFSv4.1 file layout data servers use the pNFS DS role.
Signed-off-by: Jeuk Kim <jeuk20.kim@samsung.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
|
||
|
|
2b03ebbf8d |
NFSv4/flexfiles: fix NULL dereference for NFSv4.0 data servers
flexfiles accepts NFSv4.0 data servers, but two NFSv4 code paths assume
the data server client has a session. Unlike NFSv4.1+, an NFSv4.0 client
has no session (clp->cl_session is NULL; it uses clp->cl_slot_tbl), so
I/O to a v4.0 flexfiles DS oopses:
- nfs4_init_ds_session() dereferences clp->cl_session->session_state
while seeding the DS lease. It also only seeds cl_lease_time when
NFS4_SESSION_INITING is set; without a session that never happens, so
cl_lease_time stays 0 and nfs4_renew_state() busy-loops, requeuing
every 5 seconds. Seed the lease whenever there is no session and
return before touching session state.
- ff_layout_async_handle_error_v4() dereferences
clp->cl_session->fc_slot_table on every DS I/O error. Fall back to the
v4.0 transport slot table (clp->cl_slot_tbl) when there is no session.
Fixes:
|
||
|
|
8cb1ce7aa0 |
NFSv4: pin the superblock for active state owners
NFSv4 open state can outlive the file and dentry that created it. This
was observed in production when NFSv4 state recovery, such as after a
server reboot or lease expiration, raced with unmount.
The race requires recovery to hold an open state reference while the last
open file is closed and the filesystem is unmounted, allowing the
superblock's active reference to drop to zero between
refcount_inc(&state->count) and nfs4_put_open_state():
state manager umount
nfs4_run_state_manager()
nfs4_do_reclaim()
nfs4_reclaim_open_state()
refcount_inc(&state->count)
...
close last file
generic_shutdown_super()
"Busy inodes after unmount"
nfs_free_server()
nfs4_put_open_state()
iput(inode)
evict()
nfs_clear_inode()
nfs_zap_acl_cache()
The "VFS: Busy inodes after unmount" warning is the visible symptom of
that lifetime mismatch: superblock teardown proceeds even though the NFS
open state still pins an inode. After umount has freed the server, the
state manager can then run nfs4_put_open_state() for the last open-state
reference. The resulting iput(inode) can evict an NFS inode with freed
server data, causing crashes at nfs_zap_acl_cache(). This can be
reproduced by delaying the reclaim path before nfs4_put_open_state(),
then closing the last file and unmounting the NFS mount.
Pin the superblock while a state owner is active, and drop the pin when
the owner becomes idle again, so the NFS server stays alive until all
open state associated with the owner has been released.
Assisted-by: Codex:GPT-5
Signed-off-by: Jia Zhu <zhujia.zj@bytedance.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
|
||
|
|
3e05a62a97 |
NFS/localio: issue commit inline when not in a memory-reclaim context
Extend the memory-reclaim-context test used for LOCALIO reads and writes to the commit (fsync) path. As with data IO, bouncing every commit through the dedicated !WQ_MEM_RECLAIM nfslocaliod_workqueue is only required when the submitting context is a memory-reclaim context: nfs_local_run_commit() calls vfs_fsync_range(), which may flush the underlying filesystem's own !WQ_MEM_RECLAIM workqueue, and doing so from a WQ_MEM_RECLAIM worker or a PF_MEMALLOC task trips check_flush_dependency(). The writeback path does exercise this: nfs_write_inode() (the ->write_inode super_op) runs under wb_workfn on the WQ_MEM_RECLAIM bdi_wq and reaches nfs_local_commit() via __nfs_commit_inode(), so that case must keep deferring. Application-context commits -- fsync (nfs_file_fsync), O_DIRECT (nfs_direct), and copy/clone (nfs42) -- are not in a reclaim context and now run the fsync inline via nfs_local_defer_io(), avoiding the per-commit workqueue hop. Completion (nfs_commit_release_pages -> nfs_commit_end) then runs synchronously in the submitting context; higher layers already cope with this, as __nfs_commit_inode() dispatches the commit async and waits for it separately via wait_on_commit(). Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Mike Snitzer <snitzer@kernel.org> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> |
||
|
|
b10c63dcf2 |
NFS/localio: remove dead FLUSH_SYNC handling from nfs_local_commit
nfs_local_commit() is reached only through nfs_initiate_commit(), and every
path that supplies its "how" argument has already cleared FLUSH_SYNC:
__nfs_commit_inode() strips it (how &= ~FLUSH_SYNC) before dispatch and does
its own waiting via wait_on_commit(), while the O_DIRECT path passes how=0.
filelayout issues its DS commit with a NULL localio, so it never enters
nfs_local_commit() at all. The FLUSH_SYNC branch has therefore been dead
since it was introduced with commit
|
||
|
|
da729ddd4a |
NFS/localio: issue IO inline when not in a memory-reclaim context
Every LOCALIO read and write is currently bounced through the dedicated
!WQ_MEM_RECLAIM nfslocaliod_workqueue. That bounce is only actually
required when the submitting context is a memory-reclaim context: LOCALIO
issues IO directly into a stacked local filesystem (e.g. XFS) which may in
turn flush its own !WQ_MEM_RECLAIM workqueue. Doing that from a
WQ_MEM_RECLAIM worker (most importantly writeback's wb_workfn on bdi_wq) or
an explicit PF_MEMALLOC reclaim task trips check_flush_dependency() and
risks a forward-progress deadlock, which is why commit
|
||
|
|
68c0375557 |
NFS: Fix delayed delegation return list handling
The delayed delegation return handling added a separate
delegations_delayed list to keep delegations whose return needs to be
retried later. The delayed list is then spliced back to
delegations_return by nfs_server_clear_delayed_delegations(), which also
causes the state manager to retry the delegation return.
However, nfs_end_delegation_return() still moves delayed delegations to
delegations_return instead of delegations_delayed. As a result, the new
delayed list is never populated, nfs_server_clear_delayed_delegations()
always returns false, and NFS4CLNT_DELEGRETURN is not set again to drive
a retry.
Move delayed delegations to delegations_delayed so that the delayed
return path can splice them back to delegations_return and schedule the
retry as intended.
Fixes:
|
||
|
|
3265f1998a |
NFS: Verify symlink inode before caching target
nfs_symlink() copies the symlink target into a folio before issuing the SYMLINK RPC. After a successful reply, it caches that folio in the instantiated inode mapping and assumes that the dentry now names a symlink. If the dentry is instantiated with a non-symlink inode, the raw symlink target folio can be inserted into the wrong mapping. When that inode is a directory, reclaim or unmount later calls nfs_readdir_clear_array() through nfs_dir_aops and interprets the symlink target as a readdir cache array, which can lead to invalid kfree() calls. A vmcore from a 4.19-based kernel showed the crash when reclaiming a directory mapping on unmount: Stack trace: nfs_readdir_clear_array+0x4d/0x70 [nfs] page_cache_free_page.isra.35+0x1a/0x90 delete_from_page_cache_batch+0x1cf/0x2c0 truncate_inode_pages_range+0x24d/0x910 [...] nfs_evict_inode+0x15/0x30 [nfs] evict+0x115/0x2b0 dispose_list+0x48/0x60 evict_inodes+0x16c/0x1b0 generic_shutdown_super+0x3f/0x120 nfs_kill_super+0x1b/0x40 [nfs] deactivate_locked_super+0x3f/0x70 cleanup_mnt+0x3b/0x80 The current code still has the same unchecked cache insertion pattern, so it may be susceptible to the same failure mode. Verify that the instantiated inode is a symlink before caching the target folio. If the type is wrong, drop the suspect dentry and skip the cache insertion while preserving the successful SYMLINK result. Co-developed-by: Jackie Liu <liuyun01@kylinos.cn> Signed-off-by: Jackie Liu <liuyun01@kylinos.cn> Signed-off-by: ZhangGuoDong <zhangguodong@kylinos.cn> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> |
||
|
|
59075fb8b7 |
NFS: fix folio dereference before NULL check in nfs_inode_remove_request()
nfs_inode_remove_request() obtains the folio for the head request via
nfs_page_to_folio(), which returns NULL when the PG_FOLIO flag is not
set on req->wb_head.
The presence of the "if (likely(folio))" check shows the code already
assumes folio can be NULL. However, folio was dereferenced before that
check:
folio = nfs_page_to_folio(req->wb_head);
mapping = folio->mapping; /* deref */
spin_lock(&mapping->i_private_lock);
if (likely(folio)) { /* too late */
folio->mapping is read (and mapping->i_private_lock is taken, and
folio_end_dropbehind(folio) is called outside the check) before folio
is validated, so a NULL folio would crash before the guard is ever
reached, rendering the check useless.
Move the folio->mapping read, the i_private_lock section and the
folio_end_dropbehind() call inside the "if (likely(folio))" block so
the folio is only dereferenced after it has been confirmed non-NULL.
The behaviour is unchanged when folio is non-NULL.
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
|
||
|
|
b4dd7f8159 |
nfs4.2: open UNCACHEABLE_FILE_DATA files with O_DIRECT
Honor the per-file UNCACHEABLE_FILE_DATA attribute by transparently
opening such regular files with O_DIRECT, so reads and writes bypass the
page cache as the attribute requires, without the application having to
request O_DIRECT itself.
This follows the model the specification describes: the attribute is
"similar in intent to O_DIRECT" and clients "retain flexibility in how
they satisfy the requirements" (draft-ietf-nfsv4-uncacheable-files
Section 4.4, "Relationship to Direct I/O"), and its Implementation
Status (Section 6) describes a prototype Linux client that "treats the
attribute as an indication to use O_DIRECT-like behavior for file
access".
Introduce an NFS_CONTEXT_O_DIRECT open-context flag: nfs4_atomic_open()
sets it when the resolved inode has uncacheable_file_data set (and the
open is not O_APPEND), and the open paths nfs_atomic_open() and
nfs4_file_open() apply O_DIRECT to the file when the flag is set.
The I/O mode is thus selected at open time and is not changed for an
already-open file: a later change to the attribute takes effect on the
next open. The specification permits this -- a client that has already
opened a file MAY continue with its existing caching behavior and apply
the updated attribute to subsequent operations (Section 5).
The delegation interaction in Section 4.3 was considered: it permits read
caching to remain when another NFSv4.2 mechanism, such as a delegation,
already ensures a consistent view of the file. That relaxation is
optional ("may remain appropriate") and read-only -- it does not relax
write-behind suppression (Section 4.1) or the WRITE durability invariant
(Section 4.2). This implementation deliberately does not take it: an
uncacheable file is opened O_DIRECT regardless of any delegation held,
which is compliant (read caching is simply suppressed more aggressively
than the Section 4.3 minimum) and avoids decoupling read vs write caching
behind a single open flag. Relaxing reads under a delegation is left as
a possible future optimization.
Section 6 observes the benefit holds "for applications that issue
well-formed I/O requests". That alignment caveat does not constrain the
Linux NFS client's over-the-wire path: the client readily issues
misaligned I/O using O_DIRECT over SunRPC to the remote NFS server. The
only place a fallback from O_DIRECT to buffered I/O for misaligned I/O
applies is NFS LOCALIO (fs/nfs/localio.c), which detects non-DIO-aligned
I/O and falls back internally; that path is unaffected by this change.
Link: https://datatracker.ietf.org/doc/draft-ietf-nfsv4-uncacheable-files/
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
|
||
|
|
6f36ce3098 |
nfs4.2: request UNCACHEABLE_FILE_DATA only for regular files
The UNCACHEABLE_FILE_DATA attribute applies only to regular files (NF4REG); per draft-ietf-nfsv4-uncacheable-files a server MUST reject a query of it on any other object type with NFS4ERR_INVAL. The previous commit decodes and tracks the attribute but does not gate it: the bit rides in the per-server attribute bitmask (server->attr_bitmask) and in the generic getattr request bitmap (nfs4_fattr_bitmap), so it would be requested for non-regular objects too -- e.g. a plain directory GETATTR, a LOOKUP that resolves to a directory, or a CREATE (which only ever makes non-regular objects). A strict server would fail those compounds. Gate the client accordingly: - Only set NFS_INO_INVALID_UNCACHEABLE_FILE_DATA on regular-file inodes. In particular, drop it from nfs4_update_changeattr_locked()'s force-revalidation aggregation: that helper only ever runs on directory inodes (its callers update a directory's change information after OPEN-create, REMOVE, RENAME and LINK), so it was setting the file-only bit on directories. - Gate the request by object type at the choke point nfs4_bitmap_copy_adjust(), which clears FATTR4_WORD2_UNCACHEABLE_FILE_DATA unless the target inode is a regular file (a NULL inode -- unknown object type -- clears it too). This already covers GETATTR, SETATTR and LINK; route LOOKUP, LOOKUPP and CREATE through it as well. - Type-gate nfs4_bitmask_set(), which translates NFS_INO_INVALID_UNCACHEABLE_FILE_DATA into a request for attr 87 in the getattr attached to WRITE, CLOSE and DELEGRETURN. WRITE and CLOSE only ever pass regular files, but DELEGRETURN passes whatever object held the delegation -- with directory delegation support that includes directories -- so request attr 87 there only for S_ISREG inodes. The bit is kept in server->attr_bitmask (it is server-supported, and OPEN still requests it via its regular-file-only open_bitmap), so no bespoke per-data-file bitmask plumbing is needed. The remaining getattr-bearing compounds are already safe: ACCESS and LAYOUTCOMMIT use server->cache_consistency_bitmask (no word2 attributes); READDIR does not encode the bit; and LOOKUP_ROOT, FSINFO, STATFS and PATHCONF use fixed bitmaps without it. Signed-off-by: Mike Snitzer <snitzer@kernel.org> Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> |
||
|
|
86ff184279 |
nfs4.2: add UNCACHEABLE_FILE_DATA attribute support
Recognize the NFSv4.2 per-file UNCACHEABLE_FILE_DATA attribute (attr 87, draft-ietf-nfsv4-uncacheable-files): decode it via GETATTR, track per- exported-filesystem support, and record on the inode whether a regular file's data must not be cached. Acting on the attribute (opening such files O_DIRECT) is done by a subsequent change. If the NFSv4 server reports a regular file's UNCACHEABLE_FILE_DATA as true, it indicates the file's data must not be cached; the client records this in NFS_I(inode)->uncacheable_file_data for use by the I/O paths. The UNCACHEABLE_FILE_DATA attribute applies only to regular files (NF4REG); per the draft a server MUST reject a query of it on any other object type with NFS4ERR_INVAL. A subsequent commit gates the client accordingly. Link: https://datatracker.ietf.org/doc/draft-ietf-nfsv4-uncacheable-files/ Signed-off-by: Tom Haynes <loghyr@hammerspace.com> [snitzer: adapt Tom's original code focused on metadata for ABE] Co-developed-by: Mike Snitzer <snitzer@hammerspace.com> Signed-off-by: Mike Snitzer <snitzer@hammerspace.com> Signed-off-by: Mike Snitzer <snitzer@kernel.org> Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> |
||
|
|
4a013b0e88 |
NFSv4/flexfiles: report cancelled I/O as a layout error
When a layout is recalled or revoked the client cancels its in-flight I/O so the layout can be returned. The metadata server needs to learn that this I/O to the storage device did not complete, so that it can reconcile the affected mirror instance (or, if none remains, take other action). The cancellation completed with -EAGAIN, which ff_layout_io_track_ds_error() does not recognise: it fell through the switch and recorded nothing, so no error was reported to the server. -EAGAIN is overloaded in the RPC layer, so rather than key the reporting on it, cancel the I/O with -ECANCELED and map that to NFS4ERR_NXIO in ff_layout_io_track_ds_error() -- the status the client already reports for the transport errors that leave an in-flight write incomplete. The cancelled I/O is then reported to the server via LAYOUTERROR / LAYOUTRETURN. Unlike a genuine transport error, though, we aborted the I/O ourselves and have no evidence the device is at fault, so once the error is recorded we skip marking the device unreachable and forcing a further layout return. The retry disposition is unchanged from the original -EAGAIN cancellation: both NFS4ERR_NXIO and -ECANCELED are no-ops in ff_layout_async_handle_error(), which still resets the I/O to pNFS (or the MDS), so it is re-driven as before. Signed-off-by: Benjamin Coddington <bcodding@hammerspace.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> |
||
|
|
aceaa5991b |
pNFS: honor clora_changed when recalling a layout
When the metadata server recalls a layout with clora_changed FALSE, the
layout is not changing and the client may complete its modified writes to
the storage devices before returning the layout (RFC 8881, Section
20.3.3). Only when clora_changed is TRUE -- the server is restriping, or
a storage device has failed -- should the client stop writing to the
storage devices and redirect through the metadata server.
Since commit
|
||
|
|
ba0f097418 |
pNFS: report clora_changed in the cb_layoutrecall_file tracepoint
A CB_LAYOUTRECALL carries the clora_changed flag (RFC 8881, Section 20.3.3), which tells the client whether the server is changing the layout (and therefore whether the client should flush modified data to the storage devices before returning, or stop writing to them and go through the metadata server). The client decodes this into cbl_layoutchanged, but it is otherwise invisible. Give nfs4_cb_layoutrecall_file its own event definition and report clora_changed, so the intent of a recall can be observed in a trace. Signed-off-by: Benjamin Coddington <bcodding@hammerspace.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> |
||
|
|
c056f817e4 |
pnfs/blocklayout: Fix device leaks on parse failure
bl_parse_concat() and bl_parse_stripe() allocate a child device array and
then parse each child in turn. If parsing a child fails, the failed child is
not counted in nr_children and the parent may be left with a children array
that bl_free_device() will not release when nr_children is zero.
Release the failed child and the already parsed children before returning the
error. Also make bl_free_device() release the child array whenever the
children pointer is set, so that partially initialised concat or stripe
devices are cleaned up correctly.
bl_parse_scsi() can also fail after assigning d->bdev_file and dropping the
file reference. Clear the pointer after fput() so that an outer cleanup path
does not put it again.
Fixes:
|
||
|
|
d05c2007b3 |
NFSv4: remove callback IDR entry on client allocation failure
nfs4_alloc_client() allocates an NFSv4.0 callback identifier before it
finishes setting up the client. If any later initialization step fails,
the error path frees the nfs_client directly with nfs_free_client(). That
bypasses nfs_put_client(), which is where the callback IDR entry is
removed during normal teardown.
A failed allocation can therefore leave cb_ident_idr pointing at a freed
nfs_client. A later NFSv4.0 callback lookup by cb_ident would find the
stale pointer and take a reference to it.
Make the callback IDR removal helper callable by the allocation failure
path, and remove the callback identifier before freeing the client.
This was found by a local static-analysis checker for publish-before-free
lifetime bugs and confirmed by manual inspection.
Fixes:
|
||
|
|
187bfc974e |
nfs: refactor pNFS functions using clear_and_wake_up_bit
Commit |
||
|
|
61461050da |
nfs: replace atomic bitops sequence with clear_and_wake_up_bit helper
Commit |
||
|
|
d31a688a49 |
vfs-7.3-rc1.efs
Please consider pulling these changes from the signed vfs-7.3-rc1.efs tag.
Thanks!
Christian
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJAAKCRCRxhvAZXjc
os6RAQCmvZhzfQ18Gz7FmQkeXVYJ4J1HKg0shTHdZFM+Fg+iXwD5ARD7vWqIrcxs
8etF+tlQeeB+kCiel9XJUnDfu6i1gwE=
=zo4v
-----END PGP SIGNATURE-----
mergetag object
|
||
|
|
64b0b5cacb |
fuse: wait for FR_FINISHED on abort_on_kill to prevent use-after-free
The abort_on_kill path in request_wait_answer() calls fuse_abort_conn()
and returns without waiting for FR_FINISHED. If fuse_dev_do_write() is
concurrently processing the same request (FR_LOCKED set), the caller
frees req->args while it is still being accessed, causing a
use-after-free.
Fix this by jumping to the existing wait_event(FR_FINISHED) instead of
returning early. The wait will not hang because fuse_abort_conn()
ensures all requests are ended.
Reported-by: syzbot+d6540a3fa1626e11360d@syzkaller.appspotmail.com
Fixes:
|
||
|
|
b9cba7ebfe |
vfs-7.3-rc1.binfmt
Please consider pulling these changes from the signed vfs-7.3-rc1.binfmt tag.
Thanks!
Christian
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJAAKCRCRxhvAZXjc
ovtnAQDiMF2CvH2vr/eiUEUNdDjeyzRKipkh3a9krO0XbFxpnAD8CZypBFw/oWOQ
7z3PDGhHp10ie6KYC45XbUc+a4b6vgQ=
=X9RZ
-----END PGP SIGNATURE-----
Merge tag 'vfs-7.3-rc1.binfmt' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull binfmt updates from Christian Brauner:
"This contains a bunch of work for binfmt_misc. It fixes a bunch of
old bugs, reworks the locking, and then extends the format registry
so a binary type can be matched programmatically and its interpreter
computed per exec instead of being a fixed string recorded at
registration time.
This allows nixos and other to e.g., implement relocatable binaries
meaning the interpreter/dynamic loader can be determined
programatically, say found relative to the binary. The mechanism is
flexible and can support other policies:
- Handler lookup is now an rcu walk. An exec that matches no
binfmt_misc entry should now never write to a shared cacheline
- remove the VERBOSE_STATUS and USE_DEBUG compile time toggles
- convert the entry file to a seq_file which simplifies things quite
a bit and kills a lot of custom logic
- make flags proper enums
- rename struct Node to binfmt_misc_entry
- allow entries to be removed with unlink(2)
- Add the ability to attach bpf programs to binfmt_misc entries so
it's possible to dynamically choose the execution environment such
as the loader or interpreter on a per binary basis.
A handler is an instance of a binfmt_misc_ops struct_ops with a
->match() and a ->load() program. match() decides from the entry
lookup walk whether the handler applies under the same
registration-order. It can read file content as needed not only the
prefetched 256 bytes in bprm->buf.
load() then selects the interpreter and stages it through the new
bpf_binprm_set_interp(), bpf_binprm_set_interp_arg() and
bpf_binprm_set_flags() kfuncs.
Handlers are published in a registry keyed by the registering
task's user namespace and activated through the existing text
interface with a new 'B' type carrying the handler name:
echo ':origin:B::::nix:' > /proc/sys/fs/binfmt_misc/register
The permission and namespacing model is unchanged. Activating a
handler requires the same write access to an instance as any other
registration. A container mounting its own instance escapes the
host's entries exactly as before. The computed interpreter is
opened with open_exec() under the caller's credentials and goes
through full LSM vetting as the next binprm level. A program can
only ever redirect the caller to something the caller could exec
anyway.
- Two dispatch modes are added. So far the chosen interpreter owns
the whole process identity (argv[0], /proc/pid/cmdline,
/proc/self/exe all name interpreter information). So relocatable
find the dynamic linker instead. Also a binary passed to execveat()
as an inaccessible O_CLOEXEC fd cannot run at all and gdb trips
because AT_ENTRY and AT_PHDR do not match the exe file. So PIE
symbols are unrelocated.
This adds transparent dispatch which allows the interpreter to load
the binary through AT_EXECFD and leaves the argument vector exactly
as the caller built it and labels mm->exe_file and comm with the
binary. It also raises the AT_FLAGS_TRANSPARENT_INTERP aux vector
bit. The interpreter keeps control of mapping the binary.
The second mode is loader substitution. This allows a binary to be
executed natively and only the interpreter to be changed.
- Last, interpreters can be bound at registration time. Each
interpreter is opened by its own write with the credentials the
entry file was opened with. The program picks one per exec with
bpf_binprm_select_interp().
Ucounts are used to properly account for pre-opened interpreters
via /proc/sys/user/max_binfmt_misc_interpreters"
* tag 'vfs-7.3-rc1.binfmt' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (63 commits)
binfmt_misc: document the pre-opened interpreter limit
selftests/exec: test the pre-opened interpreter limit
binfmt_misc: correctly account pre-opened interpreters
binfmt_misc: document interpreters bound by a 'B' entry
selftests/exec: test interpreters bound to a 'B' entry
binfmt_misc: let a 'B' entry bind its interpreters
binfmt_misc: carry pre-opened interpreters in struct binfmt_misc_interp
selftests/exec: share the bpf handler preconditions
binfmt_misc: document registering an entry disabled
selftests/exec: test registering an entry disabled
selftests/exec: let binfmt_flag_supported() return a bool
selftests/exec: check that a binfmt_misc instance cannot be pinned
binfmt_misc: let a register string create an entry disabled
binfmt_misc: document loader substitution
selftests/exec: test binfmt_misc loader substitution
binfmt_misc: let a bpf handler request loader substitution
binfmt_misc: add the 'L' loader substitution flag
binfmt_elf_fdpic: consume a stashed PT_INTERP substitute
binfmt_elf: consume a stashed PT_INTERP substitute
exec: carry a PT_INTERP substitute in struct linux_binprm
...
|
||
|
|
6e64df0f73 |
fuse: make dentry_tree_work static
The dentry_tree_work is not exported, so make it static to remove the followign sparse warning: fs/fuse/dir.c:37:21: warning: symbol 'dentry_tree_work' was not declared. Should it be static? Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> |
||
|
|
43f8343858 |
fuse: add zero-copy over io-uring
Implement zero-copy in fuse io-uring to eliminate memory copies between
the application, kernel, and server for read/write operations. The
server can directly access client pages or page cache folios without
copying data through an intermediary buffer. When a fuse request arrives,
the kernel registers the relevant pages into a sparse slot in the
server's io_uring registered buffer table. The server can then operate
on these pages directly using io-uring fixed buffer operations (eg
read_fixed/write_fixed) and the kernel unregisters these pages when the
request completes. Non-page-backed args (eg op out headers) will go
through the payload buffer as normal. The server can specify which open
files should have their reads/writes go through zero-copy, by setting
the FOPEN_IO_URING_ZERO_COPY flag when servicing opens.
This requires CAP_SYS_ADMIN and bufpools. This is gated behind
CAP_SYS_ADMIN because zero-copy allows the server direct access to the
client's underlying pages, rather than operating on an intermediary
buffer that the contents of the client's pages were copied into or on
page cache folios.
The request flow for the zero-copy direct-io write path (client writes
data, server reads it) is as follows:
=======================================================================
| Kernel | FUSE server
| |
| "write(fd, buf, 1MB)" |
| |
| >sys_write() |
| >fuse_file_write_iter() |
| >fuse_send_one() |
| [req->args->in_pages = true] |
| [folios hold client write data] |
| |
| >fuse_uring_copy_to_ring() |
| >copy_header_to_ring(IN_OUT) |
| [memcpy fuse_in_header] |
| >copy_header_to_ring(OP) |
| [memcpy write_in header] |
| |
| >fuse_uring_args_to_ring() |
| >setup_fuse_copy_state() |
| [skip_folio_copy = true] |
| |
| >fuse_uring_set_up_zero_copy() |
| [folio_get for each client folio] |
| [build bio_vec array from folios] |
| >io_buffer_register_bvec() |
| [register pages at
ent->zero_copy_index] |
| [ent->zero_copied = true] |
| |
| >fuse_copy_args() |
| [skip_folio_copy => return 0 |
| for page arg, skip data copy] |
| |
| >copy_header_to_ring(RING_ENT) |
| [memcpy ent_in_out] |
| >io_uring_cmd_done() |
| |
| | [CQE received]
| |
| | [issue io_uring READ at
| | ent->zero_copy_index]
| | [reads directly from
| |client's pages (ZERO_COPY)]
| |
| | [write data to backing
| | store]
| | [submit COMMIT AND FETCH]
| |
| >fuse_uring_commit_fetch() |
| >fuse_uring_commit() |
| >fuse_uring_copy_from_ring() |
| >fuse_uring_req_end() |
| >io_buffer_unregister(ent->zero_copy_index) |
| [unregister pages from index] |
| >fuse_zero_copy_release() |
| [folio_put for each folio] |
| [ent->zero_copied = false] |
| >fuse_request_end() |
| [wake up client] |
The zero-copy read path is analogous.
Some requests may have both page-backed args and non-page-backed args.
For these requests, the page-backed args are zero-copied while the
non-page-backed args are copied to the buffer selected from the buffer
pool:
zero-copy: pages registered via io_buffer_register_bvec()
non-page-backed: copied to payload buffer via fuse_copy_args()
For a request whose payload is zero-copied, the
registration/unregistration path looks like:
register: fuse_uring_set_up_zero_copy()
folio_get() for each folio
io_buffer_register_bvec(ent->zero_copy_index)
unregister: fuse_uring_req_end()
io_buffer_unregister(ent->zero_copy_index)
-> fuse_zero_copy_release() callback
folio_put() for each folio
Please note that on abort for in-flight zero-copied requests that have
been sent to userspace, the registered bvec slot remains occupied and
its folios remain pinned until the io-uring ring is destroyed, at which
point io-uring unregisters all buffers and the fuse_zero_copy_release()
callback drops the folio references. Unregistering at teardown would
require operating on the ring context directly, whose validity is hard
to ascertain; this is deemed not worth the complexity for the abort
race, since everything is freed when the ring is torn down.
The throughput improvement from zero-copy depends on how much of the
per-request latency is spent on data copying vs backing I/O. The gain
comes from eliminating the payload-buffer memcpy, but accessing the
zero-copied pages requires the server to issue the read/write as an
IORING_OP_READ/WRITE_FIXED operation. The benefit is largest when the
mempcy is a meaningful fraction of per-request latency while backing i/o
is still noticable enough that the extra io-uring op's overhead doesn't
dominate.
Benchmarked with passthrough_hp (--nopassthrough, q_depth=8) on a
2-socket Intel Xeon Gold 6138 (40 cores / 80 threads), using fio (sync
engine, bs=1M, O_DIRECT, numjobs=2, 30s run + 10s ramp, 3 runs) where
direct-I/O throughput is against a RAM-backed (tmpfs) source (backing
I/O is not the bottleneck):
baseline registered-buf zero-copy (zc vs base)
direct read ~5.1 GB/s ~5.4 GB/s ~8.9 GB/s (+75%)
direct write ~3.4 GB/s ~4.8 GB/s ~5.1 GB/s (+50%)
Reads end up higher than writes because the backing store reads faster
than it writes (the baseline shows the same read>write gap, and the raw
device does too). On a device-bound NVMe (~2 GB/s reads) the read gain
shrinks to ~10-16% (and no measurable gains for writes), as backing I/O
rather than the eliminated copy dominates latency.
The benefit overall scales with how much of the
per-request latency is the data copy versus backing I/O.
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Reviewed-by: Bernd Schubert <bernd@bsbernd.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
|
||
|
|
96caf2496e |
fuse: support registered buffer pools in io-uring
Allow servers to use a buffer pool that is also registered through io-uring. When the server registers a buffer pool with io-uring, the pages backing the pool are pinned upfront. This eliminates the overhead of pinning/unpinning user pages and translating virtual addresses per i/o request. This also allows servers to use the same registered memory for subsequent backing store I/O (eg read_fixed/write_fixed), keeping data in the same pinned pages without additional pinning or mapping overhead required. To use this, the server needs to set the FUSE_URING_REGISTERED_BUFPOOL flag when adding a bufpool through the FUSE_IO_URING_CMD_ADD_BUFPOOL cmd. For every sqe submitted (including the one for adding the bufpool), it should set sqe->uring_cmd_flags to include IORING_URING_CMD_FIXED, and pass in the index where the registered bufpool resides to sqe->buf_index. Benchmarked with passthrough_hp (--nopassthrough, q_depth=8) on a 2-socket Intel Xeon Gold 6138 (40 cores / 80 threads), using fio (sync engine, bs=1M, O_DIRECT, numjobs=2, 30s run + 10s ramp, 3 runs) where direct-I/O throughput is against a RAM-backed (tmpfs) source (backing I/O is not the bottleneck): baseline registered buffers direct read ~5.1 GB/s ~5.4 GB/s (+~5%) direct write ~3.4 GB/s ~4.8 GB/s (+~45%) Registered buffers bring up the write path speed up closer to speed of reads. There isn't much improvement for reads because it is already fast enough where it's at the copy-bound ceiling (surpassing that requires doing zero-copy). On a device-bound NVMe though, the differences are within noise, as backing I/O dominates per-request latency. Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Reviewed-by: Bernd Schubert <bernd@bsbernd.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> |
||
|
|
b45aaabc62 |
fuse: add io-uring buffer pools
Right now, ents and buffers are tightly coupled in fuse io-uring where
each entry has its own dedicated payload buffer, requiring N buffers for
N entries where each buffer must be large enough to accomodate the
maximum payload size. This is suboptimal as most request types (lookup,
open, release, getattr, etc) require vastly less bytes than the maximum
payload size and some requests (unlink, rmdir, fsync, flush, etc) do not
require payload buffers at all.
Instead of requiring a 1:1 coupling between ents and payload buffers,
allow the server to pass in a buffer pool (a contiguous chunk of memory)
that the kernel will use as it wishes for servicing ents/requests.
Entries only reserve a "buffer" from the pool while actively processing
a request that requires a payload buffer. This decoupling and letting
the kernel delegate memory from the pool for requests allows the kernel to
optimize memory usage and reduces the memory usage requirements needed
to use fuse-over-io-uring.
A pool is registered per queue with the new
FUSE_IO_URING_CMD_ADD_BUFPOOL command. The server passes the pool's base
address and length in fuse_uring_cmd_req.bufpool.{uaddr,len}.
Internally, the kernel splits the region into buffers of
ring->max_payload_sz bytes each (nr_bufs = pool len / max_payload_sz). A
queue commits to a payload mode on first use: registering an entry that
carries its own payload selects the legacy per-entry mode, while
ADD_BUFPOOL selects pool mode. The two are mutually exclusive, so
ADD_BUFPOOL must be issued before any payload-carrying entries are
registered on that queue. The queue must have been created before the
bufpool is added, through the FUSE_IO_URING_CMD_ADD_QUEUE command.
The kernel tracks free buffers with a bitmap (a set bit marks a free
buffer). On dispatch, a request that needs a payload claims a free
buffer (find_first_bit + clear). A request that needs none claims
nothing. The buffer's byte offset within the pool is reported to the
server in the new fuse_uring_ent_in_out.offset field so that the server
can locate the payload. On completion the buffer is returned to the pool
or reused directly if the next request on that entry also has a payload.
The FUSE_HAS_IO_URING_BUFPOOL flag advertises kernel support to the
server for bufpools.
Buffer pool request flow
~~~~~~~~~~~~~~~~~~~~~~~~
| Kernel | FUSE daemon
| |
| [request arrives] |
| [claim a free pool buffer] |
| >fuse_uring_select_buffer() |
| [copy headers to ring] |
| [copy payload to buffer] |
| [report buffer offset in ent_in_out] |
| >io_uring_cmd_done() |
| | [read headers]
| | [read/write payload at offset]
| | [process request]
| | >io_uring_submit()
| | COMMIT_AND_FETCH
| >fuse_uring_commit_fetch() |
| [copy reply from ring] |
| [return buffer to the pool] |
| >fuse_uring_recycle_buffer() |
Reviewed-by: Bernd Schubert <bernd@bsbernd.com>
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
|
||
|
|
ebed9ea5b4 |
fuse: add FUSE_IO_URING_CMD_ADD_QUEUE
fuse-over-io-uring queues are currently created lazily, as a side effect of the first FUSE_IO_URING_CMD_REGISTER command for a given qid. This ties queue creation to entry registration. Add a FUSE_IO_URING_CMD_ADD_QUEUE command so a server can create a queue explicitly, decoupling queue setup from entry registration. This is additionally a prerequisite for FUSE_IO_URING_CMD_ADD_BUFPOOL, which attaches a buffer pool to an existing queue and therefore needs the queue to have been created first. Reviewed-by: Bernd Schubert <bernd@bsbernd.com> Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> |
||
|
|
6330b1f61e |
fuse: decouple fuse_ring creation from ent registration
Currently, the connection's fuse_ring is created lazily on the first FUSE_IO_URING_CMD_REGISTER command. A server registers entries from one thread per queue (one per CPU) and those threads issue their first REGISTER command concurrently. They then race to create the single per-connection fuse_ring, which required open-coded handling in fuse_uring_create() to detect and protect against concurrent creations. Decouple fuse_ring creation from ent registration and move it to FUSE_INIT reply processing after a server has negotiated and set FUSE_OVER_IO_URING. The ring is published before the connection is marked initialized. fuse_uring_register() no longer creates the ring and it instead uses the ring set up at init time. Reviewed-by: Bernd Schubert <bernd@bsbernd.com> Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> |
||
|
|
7de5cf9bcf |
smb/server: fix session counter on session removal
See the procedure below:
smb2_sess_setup
ksmbd_smb2_session_create
__session_create
hash_add(sessions_table, &sess->hlist, sess->id)
ksmbd_counter_inc(KSMBD_COUNTER_SESSIONS)
ksmbd_conn_handler_loop
ksmbd_server_terminate_conn
ksmbd_sessions_deregister
hash_del(&sess->hlist)
// do not decrement KSMBD_COUNTER_SESSIONS
KSMBD_COUNTER_SESSIONS tracks sessions published in sessions_table, but
session removal does not decrement it. The value therefore keeps growing
after sessions are expired, rejected during registration, or removed on
the last channel disconnect.
Fixes:
|
||
|
|
492b24b5b6 |
smb/server: update session counter under sessions table lock
KSMBD_COUNTER_SESSIONS tracks sessions published in sessions_table.
Increment it while holding sessions_table_lock so publishing a session and
updating the counter happen together.
Fixes:
|
||
|
|
99b25b046e |
smb/server: fix session leak in ksmbd_session_register()
See the procedure below:
smb2_sess_setup
ksmbd_smb2_session_create
__session_create
atomic_set(&sess->refcnt, 2)
hash_add(sessions_table, &sess->hlist, sess->id)
ksmbd_session_register
xa_store(&conn->sessions, sess->id, sess) // fail
ksmbd_user_session_put
atomic_dec(&sess->refcnt) // refcnt is 1, session is not freed
Remove the session from sessions_table and drop its table reference if
xa_store() fails.
Fixes:
|
||
|
|
9a74739026 |
smb/server: warn if ksmbd_proc_create() fails
Print a warning if the sessions procfs entry cannot be created. Signed-off-by: Ze Tan <tanze@kylinos.cn> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
79decd88dd |
ksmbd: bound smb_check_perm_dacl() ACE walks by DACL size
smb_check_perm_dacl() validates that the DACL fits inside the NT
security descriptor, but then bounds its two ACE walks by the
remaining NTSD length (acl_size) rather than the DACL's declared
size (pdacl_size).
When pdacl->size is smaller than the trailing NTSD buffer, bytes
after the declared DACL boundary - still inside the stored security
descriptor - are parsed as ACEs during access checks. A crafted
DACL can place an access-granting ACE beyond pdacl->size, and the
current code accepts it during SMB2_CREATE access validation, while
parse_dacl() and smb_inherit_dacl() stop at pdacl_size.
Bound both ACE walks by pdacl_size to match the DACL boundary
semantics used elsewhere in the server.
Validation:
- semantic KUnit harness shows the post-boundary ACE is selected
before the fix and rejected (EACCES) after it
- linux master (7.2-rc6), x86_64
Fixes:
|
||
|
|
f7157d148d |
ksmbd: make RDMA encryption diagnostics conditional
The temporary RDMA encryption diagnostics logged every SMB3 request and successful payload operation with pr_err(), which made normal traffic too noisy. Keep only negotiation, RDMA READ preparation, RDMA WRITE transform metadata, crypto completion, and final transfer completion messages as KSMBD_DEBUG_RDMA diagnostics. Keep error reports for malformed metadata, crypto, RDMA transfer, and file write failures at error level. This preserves the diagnostics needed to verify RDMA transform operation without flooding the kernel error log during normal I/O. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
05c978948e |
ksmbd: add SMB Direct RDMA encryption transform
Port SMB Direct RDMA payload encryption support to the current ksmbd tree. The current tree already supports all-state lookup for encrypted expired sessions, so the overlapping lookup hunk from the original patch is intentionally omitted. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
6639b6928b |
ksmbd: handle encrypted compressed requests
SMB3 permits a message to be compressed before it is encrypted. After
decrypting such a request, ksmbd must trim the AEAD tag using
OriginalMessageSize, decompress the nested compression transform, and
validate the resulting SMB2 PDU.
Share the decompression helper between the connection receive path and
the post-decryption work path so unencrypted and encrypted compressed
requests follow the same validation.
Fixes:
|
||
|
|
d8fc4fc7e5 |
ksmbd: decrypt requests from expired encrypted sessions
Previous-session replacement marks the old session expired but retains its
SMB3 encryption key. An in-flight encrypted request can still arrive on
that connection. Rejecting the expired session before decryption made ksmbd
treat the request as a key failure and abort the transport, causing
reconnect failures.
Allow key lookup for expired sessions that have encryption enabled. Keep
the session reference during validation so the normal
STATUS_USER_SESSION_DELETED response is encrypted with the old key. The
session remains expired and no command is executed.
Fixes:
|
||
|
|
12a6680ce5 |
ksmbd: disconnect on SMB3 decryption failure
MS-SMB2 requires the server to disconnect a connection when an
encrypted transform cannot be associated with a session or fails
authenticated decryption. This includes an encrypted request that
still carries a SessionId invalidated through PreviousSessionId.
Move the connection to EXITING and shut down its transport when
decrypt_req() fails. Add the missing TCP shutdown callback so a receive
blocked in kernel_recvmsg() is released; SMB Direct already provides
the corresponding callback.
Plaintext requests using an invalidated SessionId do not take this
path and continue to receive STATUS_USER_SESSION_DELETED.
Fixes:
|
||
|
|
2a0e037648 |
ksmbd: encrypt interim responses to encrypted requests
The normal response path applies an SMB3 transform when the request was
encrypted. Async interim responses, completed compound prefixes and two
CHANGE_NOTIFY cleanup paths write their synthetic response work directly,
bypassing that encryption step.
A packet capture shows FE SMB2 STATUS_PENDING, CREATE and CHANGE_NOTIFY
responses following FD SMB3 requests. The client resets the connection
immediately after receiving those plaintext responses.
Send synthetic interim work through a common helper that applies the
session encryption transform first. A compound prefix shares the original
work's response iov, which encryption would replace in place, so flatten it
into an independently owned work before encrypting and sending it.
Fixes: 64bfa9d49026 ("smb/server: use MSG_EOR for async interim response")
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
|
||
|
|
c50e628122 |
ksmbd: scope session state changes to bound connections
ksmbd_all_conn_set_status() treats every connection whose transient binding flag is set as belonging to the target SessionId. A logoff or session replacement can consequently move an unrelated connection to NEED_RECONNECT or NEED_SETUP. Pass the target session itself and select connections using either the connection-local session xarray or the session's permanent channel list. Use the same association test while waiting for requests to drain. Serialize session-wide status changes under request_lock and do not overwrite EXITING or RELEASING. Protect the shutdown transition with the same lock so a concurrent session update cannot revive a closing connection. Fixes: |
||
|
|
2cbd4a8bf4 |
ksmbd: fix encrypted request lookup on bound channels
An SMB3 multichannel binding registers the secondary connection in the
session channel list, but does not insert the session into the secondary
connection's session xarray.
The decryption path only searches the connection-local xarray. As a
result, every encrypted request received on a bound channel fails with
"Could not get decryption key".
Use the channel-aware session lookup for decryption. Also stop using the
temporary conn->binding flag to decide whether the global lookup is
allowed. Validate the permanent channel association under chann_lock
instead.
Fixes:
|
||
|
|
50a400cff5 |
ksmbd: add per-share SMB3 encryption enforcement
Add a share flag for requiring SMB3 encryption on an individual share. Advertise SMB2_SHAREFLAG_ENCRYPT_DATA in TREE_CONNECT responses and reject both unencrypted TREE_CONNECT attempts and plaintext requests for shares carrying the flag. Keep BIT(19) reserved for the existing ksmbd-tools WIDE_LINKS flag and use BIT(20) for the new netlink ABI flag. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
abe5acb342 |
ksmbd: notify parent directory leases on child create
BVT_DirectoryLeasing_ReadWriteHandleCaching requires a parent directory lease break notification when another client creates a child in the leased directory. A child CREATE without a lease context did not notify the parent lease holders because the notification path expected a non-NULL lease context. Allow the parent lease notification helper to handle a NULL child lease context and notify matching parent leases. Invoke it after a child is created without a lease context while preserving the existing lease-key filtering for requests that provide one. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
5213c36863 |
ksmbd: implement SMB2 AppInstanceVersion takeover
BVT_AppInstanceVersion_SMB311_GreaterVersion, BVT_AppInstanceVersion_SMB311_SameVersion, BVT_AppInstanceVersion_SMB311_LowerAppInstanceVersionHigh, and BVT_AppInstanceVersion_SMB311_LowerAppInstanceVersionLow exercise ordered opens using the same AppInstanceId. ksmbd tracked the AppInstanceId, but did not parse the version context or enforce the version ordering, so versioned opens returned incorrect sharing violations. Parse and retain the 24-byte AppInstanceVersion context with each open. Reject a version that is lower than or equal to the active version with STATUS_FILE_FORCED_CLOSED, reject an unversioned open against a versioned handle, and close the previous handle for a newer takeover. Do not apply the takeover check to durable reconnect or replay requests. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
68f3508e4c |
ksmbd: accept unspecified volatile ID on durable reconnect
BVT_DurableHandleV1_Reconnect_WithBatchOplock, BVT_DurableHandleV1_Reconnect_WithLeaseV1, BVT_DurableHandleV2_Reconnect_WithBatchOplock, and BVT_DurableHandleV2_Reconnect_WithLeaseV1 fail to reconnect a durable handle when the request leaves VolatileFileId unset. A durable reconnect request may omit VolatileFileId by setting it to zero. Treating zero as an ID makes ksmbd reject the request whenever the saved volatile ID is nonzero. Only compare the saved and requested volatile IDs when the request contains a nonzero value. Explicit mismatches continue to be rejected. This allows SMB2 durable handle V1 and V2 reconnects that identify the handle through the persistent ID and reconnect context. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
39f2032096 |
smb/server: fix tree connection leak in smb2_tree_connect()
See the procedure below:
smb2_tree_connect
ksmbd_tree_conn_connect
xa_store(&sess->tree_conns, tree_conn->id, tree_conn)
ksmbd_counter_inc(KSMBD_COUNTER_TREE_CONNS)
ksmbd_share_tree_conn_inc(sc)
ksmbd_iov_pin_rsp // fail
status.ret = KSMBD_TREE_CONN_STATUS_NOMEM
// do not disconnect tree_conn
Disconnect the new tree connection if ksmbd_iov_pin_rsp() fails.
Fixes:
|
||
|
|
4818df5aaa |
ksmbd: wait for deferred notify cancellation
A cancelled SMB2 CHANGE_NOTIFY request is completed from system_wq. The deferred work keeps a reference to the connection, but it is not included in the connection's r_count. During connection teardown, ksmbd_conn_transport_destroy() can therefore finish the connection handler and destroy session proc entries before the deferred response runs. Account for the deferred cancellation work in r_count. The connection handler now waits for the deferred response to finish before it deregisters sessions and removes their proc entries. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
93a3cda161 |
smb/server: fix use-after-free in ksmbd_conn_transport_destroy()
Reproducer (Link[1]): 1. Build kernel with CONFIG_KASAN=y 2. server: systemctl start ksmbd 3. client: mount -t cifs //localhost/export /mnt 4. client: umount /mnt 5. server: modprobe -r ksmbd The error message is as follows: ================================================================== BUG: KASAN: slab-use-after-free in proc_remove+0x3e/0x80 Read of size 8 at addr ffff88810654e098 by task modprobe/785 ... Call Trace: <TASK> __dump_stack+0x19/0x30 dump_stack_lvl+0x49/0x60 print_address_description+0x7b/0x200 print_report+0x5b/0x70 kasan_report+0xed/0x130 __asan_report_load8_noabort+0x18/0x20 proc_remove+0x3e/0x80 ksmbd_conn_transport_destroy+0x2b/0x320 [ksmbd] cleanup_module+0x33/0xe00 [ksmbd] __se_sys_delete_module+0x276/0x400 __x64_sys_delete_module+0x5f/0x70 x64_sys_call+0x2675/0x3030 do_syscall_64+0xf0/0x3b0 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7f5b56d2b02b ... </TASK> Allocated by task 159: kasan_save_track+0x2f/0x70 kasan_save_alloc_info+0x40/0x50 __kasan_slab_alloc+0x52/0x70 kmem_cache_alloc_noprof+0x168/0x3e0 __proc_create+0x20b/0x710 proc_create_single_data+0x78/0x150 ksmbd_proc_create+0x24/0x30 [ksmbd] ksmbd_conn_transport_init+0x4f/0x80 [ksmbd] server_ctrl_handle_work+0x64/0x2c0 [ksmbd] process_scheduled_works+0x788/0xec0 worker_thread+0x894/0xc10 kthread+0x2e5/0x3c0 ret_from_fork+0x168/0x4f0 ret_from_fork_asm+0x1a/0x30 Freed by task 785: kasan_save_track+0x2f/0x70 kasan_save_free_info+0x4a/0x60 __kasan_slab_free+0x47/0x70 kmem_cache_free+0x122/0x410 pde_put+0xfd/0x160 remove_proc_subtree+0x365/0x540 proc_remove+0x6a/0x80 ksmbd_proc_cleanup+0x1f/0x60 [ksmbd] cleanup_module+0x18/0xe00 [ksmbd] __se_sys_delete_module+0x276/0x400 __x64_sys_delete_module+0x5f/0x70 x64_sys_call+0x2675/0x3030 do_syscall_64+0xf0/0x3b0 entry_SYSCALL_64_after_hwframe+0x76/0x7e ================================================================== Reported-by: Kyenghwan Hwang <obnred@gmail.com> Link[1]: https://lore.kernel.org/linux-cifs/8ea028f5-90f4-4d21-b1ac-a343f0f04d88@chenxiaosong.com/ Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
215e8816b1 |
ksmbd: detach blocked lock requests before freeing
A file_lock retained by ksmbd for byte-range lock bookkeeping can still
be part of the VFS blocked-request graph. In particular, the VFS can
chain a new waiter below an already blocked request through
flc_blocked_requests. The ksmbd_file reference count does not cover that
graph.
Both __ksmbd_close_fd() and the cross-request unlock path free these
retained file_lock objects directly. If a dependent waiter is still
attached, locks_release_private() hits
BUG_ON(!list_empty(&flc->flc_blocked_requests)). The same lifetime
mismatch can leave a freed ksmbd_lock reachable through its request-local
llist.
Detach the file_lock from the blocked-request graph before freeing it in
the close, cross-request unlock, and rollback paths. locks_delete_block()
also wakes requests chained below the object. Remove llist when a
completed lock is published so a globally visible ksmbd_lock no longer
points into the submitting worker's stack.
Fixes:
|
||
|
|
5b90f78dc2 |
smb: server: Clear Preauth_HashValue in smb2pdu.c with kfree_sensitive()
struct preauth_session contains the Preauth_HashValue[] array that might contain sensitive data. Use kfree_sensitive() to clear it before returning the memory to the heap. Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
0cb81ed8b5 |
smb: server: Free sensitive data in connection.c with kfree_sensitive()
struct ksmbd_conn contains an embedded struct ntlmssp_auth with the ciphertext[] and cryptkey[] arrays, so to avoid leaking this information via the heap, it should be freed with kfree_sensitive(). While we're at it, also use kfree_sensitive() for freeing preauth_info in ksmbd_conn_free() to avoid that the Preauth_HashValue[] could leak via the heap here, too. Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
9a4bd6507c |
smb: server: Free session data in user_session.c with kfree_sensitive()
struct ksmbd_session contains some arrays with sensitive information, like sess_key, smb3encryptionkey, smb3decryptionkey and smb3signingkey. Thus let's make sure that this information cannot leak via the heap and use kfree_sensitive() to free it. Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
2c5a176882 |
smb: server: Make sure that passkey is not leaked on the heap in user_config.c
Use kfree_sensitive() to free the user->passkey (and the struct ksmbd_login_response in ksmbd_login_user() that contains the same information) to avoid that this information could leak somewhere else via the heap. Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
9a9f1342da |
smb: server: Clear sensitive stack and heap data in auth.c
Sensitive data like keys that are stored in stack-local arrays could be leaked via the stack to the calling functions, or via the heap when using only normal kfree() functions. There is no known vulnaribility for this right now, but it's good security style to explicitly zeroize this sensitive matieral as soon as possible to avoid that it could be exploited together with other bugs later. In calc_ntlmv2_hash(), the struct hmac_md5_ctx is normally cleared during hmac_md5_final() already, but in case of errors, this function is skipped and ctx is never zeroized, so add a memzero_explicit(&ctx, sizeof(ctx)) there to fix the problem. In ksmbd_krb5_authenticate(), the ksmbd_spnego_authen_response contains the session key in the payload. It's currently freed with plain kvfree(). Let's better use kvfree_sensitive() instead. In generate_key(), the prfhash[] array is used to calculate the key, but it's never cleared, so it leaks on the stack. Thus clear this with a memzero_explicit(), too. In ksmbd_crypt_message(), the sign[] and key[] arrays are leaked via the stack, too. Make sure to clear them via memzero_explicit() at the end. Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
23a0be6a84 |
ksmbd: fix heap out-of-bounds write in krb5_authenticate()
In krb5_authenticate(), out_len is calculated to determine available headroom in response_buf for the incoming Kerberos AP-REP token. However, when SMB2_SESSION_SETUP is processed as a non-first element of a compounded SMB2 request, the calculation omits work->next_smb2_rsp_hdr_off. This causes out_len to overstate remaining buffer headroom by the cumulative size of prior responses in the compound chain. Consequently, the length check in ksmbd_krb5_authenticate() (*out_len <= resp->spnego_blob_len) passes erroneously, allowing memcpy() to write the AP-REP blob past the end of response_buf into adjacent kernel heap memory. Fix this by subtracting work->next_smb2_rsp_hdr_off when computing out_len, ensuring it accurately reflects physical remaining buffer space. Signed-off-by: Ilan Dudnik <ilan.dudnik@safebreach.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
6a8292d379 |
smb/server: deny overwriting targets with non-POSIX opens
Reproducer:
1. server: systemctl start ksmbd
2. client: mount without `posix` option
mount -t cifs //${server_ip}/export /mnt
3. client: touch /mnt/file1 /mnt/file2
4. client: C program: int fd = open("/mnt/file2", O_RDONLY);
5. client: C program: rename("/mnt/file1", "/mnt/file2");
6. client: C program: struct stat stbuf; fstat(fd, &stbuf);
stbuf.st_nlink is 1, should be 0
This patch fixes xfstests generic/035 when mounted without `posix` option.
Suggested-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
|
||
|
|
1e3b4b4f77 |
smb/server: rename to ksmbd_has_nonposix_open_child()
The original function name `ksmbd_has_open_files()` could be confused with the function name introduced in the next patch, and it does not accurately describe what this function does. Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
988c3c186c |
erofs: fix unused pcluster_pools for higher page sizes
pcluster_pool[] hardcodes {1,4,16,64,128,Z_EROFS_PCLUSTER_MAX_PAGES+1},
but the assumption of Z_EROFS_PCLUSTER_MAX_PAGES == 256 is only right
for 4k page sizes. For higher page sizes like 16k or 64k, This results
in us ending up with clusters bigger than what we will ever use, since
we only support upto 1MB of compressed data. For example, on 64k page
size we will only ever use clusters with nrpages= 1, 4 and 17.
This patch fixes the allocation for such higher pages sizes by adding
some compile time checks.
Below are the clusters created right after boot on a 64KB page size
machine
$cat /proc/slabinfo | grep pcluster | cut -d" " -f1:
Before the patch:
erofs_pcluster-1
erofs_pcluster-4
erofs_pcluster-16
erofs_pcluster-17
erofs_pcluster-64
erofs_pcluster-128
After the patch:
erofs_pcluster-1
erofs_pcluster-4
erofs_pcluster-17
Fixes:
|
||
|
|
6847d4d1a2 |
erofs: guard on-disk algorithm IDs against Z_EROFS_COMPRESSION_MAX
All on-disk algorithm IDs should be validated against
supported Z_EROFS_COMPRESSION_MAX.
This includes a partial revert of a previous commit and also adds
validation for encoded extents.
Fixes:
|
||
|
|
862427ebb8 |
erofs: fix interlaced ztailpacking pclusters
On-disk sizes of interlaced pclusters should be block-aligned, and
ztailpacking interlaced pclusters should be invalid at all.
Currently, mkfs.erofs won't generate any interlaced pcluster with
ztailpacking enabled, so this doesn't affect any existing valid
filesystems.
However, crafted images can contain invalid interlaced ztailpacking
pclusters, resulting in an out-of-bounds read from a kmap'd page and
copying irrelevant kernel memory into userspace-visible page cache.
Reported-by: Haiyang Huang <huanghaiyang83@gmail.com>
Closes: https://lore.kernel.org/r/20260806065253.1083865-1-huanghaiyang83@gmail.com
Fixes:
|
||
|
|
490529f668 |
exfat: replace truncate_lock with inode_lock
Remove the per-inode truncate_lock and rely on inode_lock instead. exfat_setattr() truncates under inode_lock (held exclusively by the VFS callers), and exfat_aop_bmap() now takes inode_lock shared to exclude a concurrent truncate, providing the same mutual exclusion with a single lock. Signed-off-by: Chi Zhiling <chizhiling@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
2d99fbd7ad |
smb/server: fix posix state check for directory rename
Pass the source ksmbd_file to the rename helpers and use the per-handle
POSIX create-context state when deciding whether open children block a
directory rename.
work->tcon->posix_extensions only records whether POSIX extensions were
negotiated on the connection. It does not indicate that the handles were
opened with POSIX create contexts.
Reproducer:
1. server: systemctl start ksmbd
2. client: mount -t cifs //${server_ip}/export /mnt
# without posix option
3. client: mkdir /mnt/dir1/; touch /mnt/dir1/file
4. client: tail -f /mnt/dir1/file # open file
5. client: mv /mnt/dir1 /mnt/dir2
Without this fix, the rename can succeed when it should fail with
"Permission denied".
Fixes:
|
||
|
|
a3bcea7c81 |
ksmbd: exempt FSCTL_PIPE_TRANSCEIVE from the generic file-id lookup
smb2_ioctl() rejects FSCTL_PIPE_TRANSCEIVE with STATUS_OBJECT_NAME_NOT_FOUND before fsctl_pipe_transceive() runs. RPC pipe IDs live in sess->rpc_handle_list, a separate namespace from the ksmbd_file table the generic ksmbd_lookup_fd_slow() gate searches, so the lookup always misses. Found while testing generic SMB browsing (Finder's "Connect to Server"): every DCE/RPC bind over a named pipe (SRVSVC, WKSSVC, SAMR, LSARPC) failed right after CREATE. Adding FSCTL_PIPE_TRANSCEIVE to the same no_fileid_ioctl exemption as FSCTL_PIPE_WAIT fixes it, confirmed by testing a build with and without the change. Signed-off-by: Gael Blivet <gael.blivet@gmail.com> Assisted-by: Claude:claude-sonnet-5 Tested-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
29f74f0f2e |
ksmbd: defer publishing granted locks to prevent UAF/double-free race
In smb2_lock(), mid-batch granted locks are published to connection-wide
(conn->lock_list) and file-wide (fp->lock_list) lists immediately upon
vfs_lock_file() success, while also remaining tracked on the stack-local
rollback_list.
If a subsequent element in the same SMB2_LOCK request array fails
validation or execution, the thread jumps to out: and walks
rollback_list to undo previously granted locks. However, because the
granted lock was already published to conn->lock_list, a concurrent
UNLOCK request on the same connection can find the lock object and
kfree() it before the rollback loop executes.
When the granting thread subsequently walks rollback_list, it
dereferences and frees the already-freed ksmbd_lock structure, resulting
in a Use-After-Free and Double-Free (on both ksmbd_lock and struct
file_lock).
Fix this by deferring the publication of granted locks to
conn->lock_list and fp->lock_list until after the entire array of lock
elements has been processed without error. Mid-batch grants remain
tracked exclusively on the request-local rollback_list until the whole
batch succeeds, eliminating the race window.
Fixes:
|
||
|
|
3a98de41b0 |
ksmbd: fix use-after-free in lease break notification
smb2_lease_break_noti() selects a connection from a shared lease table,
but reads lease->l_lb without lease_list_lock. Connection teardown can
free the table before the notification takes a reference to the selected
connection.
Select and pin the connection while holding the lock protecting its
lifetime, before the allocations that may sleep. Also protect the owner
connection lookup with ci->m_lock, since session reconnect can clear
opinfo->conn under that lock. Transfer the reference to the notification
work and release it on allocation failures or in the existing work cleanup
path.
Fixes:
|
||
|
|
73541bd2ba |
smb/server: preserve error status in smb2_handle_negotiate()
smb2_handle_negotiate() records specific failures such as
STATUS_INVALID_PARAMETER or STATUS_NOT_SUPPORTED.
Fixes:
|
||
|
|
f43cbe3b58 |
smb/server: call ksmbd_proc_cleanup() on module init failure
When a later initializer fails, the unwind chain releases resources
created after procfs and then jumps directly to class_unregister().
Returning an error from module_init() leaves the proc tree and its
per-CPU counters allocated.
Fixes:
|
||
|
|
db97f37637 |
smb/server: abort initialization when proc setup fails
ksmbd_server_init() calls ksmbd_proc_init() before creating the
remaining proc entries and server subsystems. ksmbd_proc_init() tears
down partial state on a procfs or percpu_counter allocation failure,
but returns void, so ksmbd_server_init() continues as if the counters
were usable.
Once userspace starts the server, server_ctrl_handle_init() calls
ksmbd_proc_reset(), which reaches percpu_counter_set() with a NULL
per-CPU counters pointer on SMP systems. The later ksmbd_proc_create()
calls also receive a NULL parent and may create entries in the /proc
root; ksmbd_proc_cleanup() cannot remove those entries because
ksmbd_proc_fs is NULL.
Fixes:
|
||
|
|
bef46b6047 |
smb/server: fix invalid pointer dereference in ksmbd_stop_durable_scavenger()
See the procedure below:
ksmbd_launch_ksmbd_durable_scavenger
durable_scavenger_running = true
server_conf.dh_task = kthread_run() // fail, dh_task is an ERR_PTR()
server_ctrl_handle_reset
ksmbd_stop_durable_scavenger
kthread_stop(server_conf.dh_task) // invalid pointer
Fixes:
|
||
|
|
3ce2f94919 |
smb/server: fix memory leak in ksmbd_vfs_set_durable_owner()
See the procedure below:
smb2_open
ksmbd_vfs_set_durable_owner
fp->owner.name = name
// When the connection goes away
ksmbd_sessions_deregister
ksmbd_session_destroy
ksmbd_destroy_file_table
__close_file_table_ids
session_fd_check // skip()
ksmbd_vfs_set_durable_owner
fp->owner.name = name // memory leak
Signed-off-by: ZhangGuoDong <zhangguodong@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
|
||
|
|
d2ccf905f4 |
smb/server: fix null-ptr-deref in ksmbd_ipc_tree_connect_request()
See the procedure below:
ksmbd_tree_conn_connect
ksmbd_share_config_get
share->name = kstrdup() // fail
if (!test_share_config_flag(share, KSMBD_SHARE_FLAG_PIPE)) // false
// do not check `share->name`
ksmbd_ipc_tree_connect_request
strlen(share->name) // null-ptr-deref
Fixes:
|
||
|
|
6eac877e0e |
ksmbd: remove extra byte from ipc_msg_alloc() size calculations
Three ipc_msg_alloc() calls in transport_ipc.c allocate sizeof(struct) + payload_len + 1, but the extra byte is unnecessary. The payload data is binary and copied with memcpy() to the exact size; no null terminator is needed. This was present in the original commit that introduced the file, where the structs already used [0] zero-length arrays, so the +1 was never correct. Assisted-by: Opencode:Big-Pickle Signed-off-by: Rosen Penev <rosenp@gmail.com> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
16a7f7c2ec |
ksmbd: reject blocking compound lock requests
Clients set SMB2_LOCKFLAG_FAIL_IMMEDIATELY when a LOCK request contains multiple lock elements, and servers reject requests that omit it. Accepting such a request can leave earlier elements locked while a later element waits asynchronously, enabling prolonged partial lock ownership and avoidable deadlocks. Return STATUS_INVALID_PARAMETER before processing any element when a multi-element lock request contains a blocking lock. Unlock arrays remain unaffected. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
054bcca4cd |
ksmbd: safely discard unregistered deferred locks
When vfs_lock_file() defers a lock, smb2_lock() puts its ksmbd_lock on rollback_list before allocating and registering the asynchronous work. If either operation fails, rollback assumes that smb_lock->conn is initialized and dereferences NULL. The deferred file_lock also remains linked into the VFS blocked-lock state while it is freed. Keep the lock off rollback_list until async setup succeeds. On setup failures, explicitly unblock and wake the deferred lock before freeing it and its ksmbd wrapper. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
5ce5227cd6 |
ksmbd: recognize replayed SMB2 lock sequences
A server returns success without processing a lock request when a valid LockSequenceArray entry contains the same sequence number. The current verifier only invalidates mismatched entries, so matching requests are submitted to the VFS again and recorded as duplicate locks. Make the verifier report matching sequences and skip lock processing for those replays. Also correct the field comment to describe the sequence and index bit layout used by the implementation and the protocol. Use the capabilities advertised by the server when deciding whether lock sequence verification applies to a multichannel connection. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
54d90311f9 |
ksmbd: fix SMB2 byte-range lock end offset
SMB2 describes a byte-range lock using an offset and a length, while Linux file_lock uses an inclusive end offset. smb2_lock() currently sets fl_end to start + length and consequently locks one extra byte for every nonzero-length request. Translate nonzero lengths to start + length - 1 and reject ranges that cannot be represented by loff_t instead of silently truncating them at OFFSET_MAX. Track zero-length locks from the request length so one-byte ranges are not mistaken for zero-length locks after endpoint conversion. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
b0148dc562 |
ksmbd: serialize oplock close with pending break ownership
close may abort an in-flight oplock break while another breaker already
holds an opinfo reference. Releasing pending_break wakes that waiter, but
without serializing the close transition with bit acquisition it can become
a new break owner through the test_and_set_bit() fast path. It can then
overwrite OPLOCK_CLOSING with OPLOCK_ACK_WAIT and continue a break for
a dying opinfo.
Make OPLOCK_CLOSING terminal once the opinfo is removed from the inode
list. Serialize that transition, pending_break acquisition, and
OPLOCK_ACK_WAIT setup with an opinfo state lock. A breaker which loses
the race releases its ownership and returns -ENOENT. Explicitly wake
pending_break waiters during close so they can observe the terminal state.
Also prevent ACK and timeout paths from replacing OPLOCK_CLOSING with
OPLOCK_STATE_NONE.
Fixes:
|
||
|
|
f39ec312c3 |
smb/server: fix unbuffered file position alignment check
FILE_NO_INTERMEDIATE_BUFFERING is a CreateOptions flag and can be combined with other flags, such as FILE_NON_DIRECTORY_FILE. Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
a47634cd72 |
ksmbd: expire SMB sessions when Kerberos tickets expire
Store the expiry time from the Kerberos authentication response in the session and reject requests after that time with STATUS_NETWORK_SESSION_EXPIRED. Allow an expired Kerberos session to be reauthenticated. Keep the old SMB signing key until its SESSION_SETUP response has been signed, then install the new session key and regenerate the SMB3 keys. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
84c41b731b |
ksmbd: stabilize allocation size after buffered writes
Ordinary opens initialize their allocation size from stat.blocks. Buffered writes can leave delayed allocation pending, so separate handles can cache different block counts for the same file. This makes generic/568 fail when a zero write used for fallocate emulation is followed by an overwrite of the same range. The first query can report the pre-writeback block count, while the second query reports the block count after delayed allocation is completed. Complete writeback and refresh the cached block count before returning allocation information for ordinary opens. Track client-specified allocation sizes separately so CREATE allocation contexts and FILE_ALLOCATION_INFORMATION continue to return the requested value. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
25e414db70 |
ksmbd: report holes in allocated range queries
FSCTL_QUERY_ALLOCATED_RANGES treated every range in a file without the sparse attribute as allocated. Files can have holes after an ordinary write beyond EOF, so CIFS FIEMAP reported extents for those holes. SEEK_DATA and SEEK_HOLE are insufficient because unwritten extents look like holes. Use zero writes for FSCTL_SET_ZERO_DATA on dense files. Sparse files still use hole punching, and allocated-range queries can use SEEK_DATA and SEEK_HOLE for both file types. When clearing the sparse attribute, materialize holes with zero writes before updating the attribute. This keeps the file fully allocated without relying on unwritten extents that SEEK_DATA would still report as holes. Return STATUS_BUFFER_OVERFLOW when another allocated range does not fit in the SMB response so the client continues the query. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
3f220a0a62 |
ksmbd: only rebind the reopened file's own oplock on durable reconnect
ksmbd_reopen_durable_fd() walks the inode's m_op_list and rebinds every
detached oplock to the reconnecting session:
list_for_each_entry_rcu(op, &ci->m_op_list, op_entry,
lockdep_is_held(&ci->m_lock)) {
if (op->conn)
continue;
op->conn = ksmbd_conn_get(fp->conn);
op->sess = work->sess;
}
The only key is op->conn == NULL, which every detached durable handle on
that inode matches, not just the one owned by fp. When two sessions hold
durable handles on the same file and both disconnect, reconnecting one of
them adopts the other session's oplock: op->sess is overwritten with the
reconnecting session without taking a reference on it, while op->conn
pins the connection.
The sibling teardown path, session_fd_check(), keys on the identity of
the connection being torn down (op->conn == conn) rather than on shared
state, and so does not have this problem.
Once the adopting session is destroyed, ksmbd_session_destroy() frees it
while the foreign oplock still points at it. The reader in
ksmbd_close_fd_app_instance_id() validates only opinfo->conn, which is
still live thanks to the reference taken above, and then dereferences the
stale session:
if (!opinfo->conn) {
up_read(&fp->f_ci->m_lock);
goto out;
}
ft = &opinfo->sess->file_table;
write_lock(&ft->lock);
BUG: KASAN: slab-use-after-free in _raw_write_lock+0x74/0xd0
Write of size 4 at addr ffff88810a970528 by task kworker/0:0/9
Workqueue: ksmbd-io handle_ksmbd_work
Call Trace:
_raw_write_lock+0x74/0xd0
ksmbd_close_fd_app_instance_id+0x183/0x410
smb2_open+0x1346/0x4430
handle_ksmbd_work+0x2bb/0x7b0
Reached from an authenticated session against a share with the default
durable-handle and oplock configuration: two sessions open the same file
with a durable-v2 handle and an RH lease under distinct AppInstanceIds,
both log off, one reconnects with DH2C, and a later durable-v2 create
carrying the other AppInstanceId walks into the freed session.
Constrain the loop to the oplock owned by the file being reopened.
Fixes:
|
||
|
|
06c7b1d731 |
ksmbd: free preauth sessions on connection teardown
SMB3.1.1 multichannel binding preserves the preauthentication hash in a
preauth_session between the NTLM negotiate and authenticate requests.
The binding NTLM negotiate allocates this object and returns
STATUS_MORE_PROCESSING_REQUIRED. If the client disconnects before it sends
the authenticate request, neither the authenticate nor error cleanup paths
free the object.
Release any remaining preauthentication sessions when tearing down the
connection. Initialize the list when allocating the connection so that this
cleanup is safe regardless of the negotiated dialect.
Reported-by: Runa Takemoto <takemotoruna223@gmail.com>
Fixes:
|
||
|
|
528af7cf69 |
smb/server: avoid registering async requests during connection close
A connection-close scan can miss the synthetic CHANGE_NOTIFY work item because smb2_notify() registers it directly after setup_async_work() has returned. Link both regular and synthetic async work through one helper that checks the connection state under request_lock. If the connection is already closing, release a newly allocated async ID or complete the synthetic notify work immediately. Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Co-developed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
4fd5bad647 |
smb/server: cancel async requests when closing connection
An async request may still be waiting when a connection is closed. This can stop the connection from closing. Cancel active async requests before waiting for them to finish. Suggested-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
df3e2150f3 |
smb/server: fix signing when a response uses more than one iov
Some SMB responses keep their data in another buffer. The SMB header and the data are then in different iovs. The old code only handled this for SMB2 READ. For other commands, it signed only the last iov. QUERY_INFO and CHANGE_NOTIFY can also use another iov for their data. Their SMB header was not signed, so Windows will client rejected the response. Find the iov that starts with the current SMB header. Sign this iov and all iovs after it. Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> |
||
|
|
e9b33376bd |
ksmbd: validate ipc response length before dereferencing its fields
ipc_validate_msg() computes the expected message size by reading length
fields out of the response buffer supplied by the userspace ksmbd daemon
(payload_sz, session_key_len, ngroups, ...). Those fields are read before
the buffer is verified to be large enough to contain the struct they belong
to, so a short response makes the read land past the end of the allocation.
handle_response() sizes entry->response purely from the netlink attribute
length (nla_len()) and only guards the leading handle read, so the daemon
can install a response as small as the kmalloc-8 object seen below. When
ipc_msg_send_request() then calls ipc_validate_msg() for a
KSMBD_EVENT_RPC_REQUEST, the cast to struct ksmbd_rpc_command reads
resp->payload_sz at offset 8 of an 8-byte allocation:
[ 3697.841381] ==================================================================
[ 3697.844099] BUG: KASAN: slab-out-of-bounds in ipc_msg_send_request+0x763/0x800
[ 3697.846604] Read of size 4 at addr ffff888105f95910 by task kworker/4:3/20682
[ 3697.849061]
[ 3697.849801] CPU: 4 UID: 0 PID: 20682 Comm: kworker/4:3 Not tainted 7.2.0-rc3-next-20260717-virtme #117 PREEMPT(lazy)
[ 3697.850077] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
[ 3697.850303] Workqueue: ksmbd-io handle_ksmbd_work
[ 3697.850592] Call Trace:
[ 3697.850794] <TASK>
[ 3697.850952] __dump_stack+0x21/0x60
[ 3697.851239] dump_stack_lvl+0xc2/0x100
[ 3697.851528] print_address_description+0x77/0x200
[ 3697.851816] ? ipc_msg_send_request+0x763/0x800
[ 3697.852024] print_report+0x58/0x70
[ 3697.852316] kasan_report+0x117/0x150
[ 3697.852585] ? down_write+0x146/0x1f0
[ 3697.852809] ? ipc_msg_send_request+0x763/0x800
[ 3697.853082] ipc_msg_send_request+0x763/0x800
[ 3697.853385] ? __pfx_ipc_msg_send_request+0x10/0x10
[ 3697.853604] ? kasan_unpoison+0x48/0x70
[ 3697.853936] ? __pfx___up_read+0x10/0x10
[ 3697.854221] ksmbd_rpc_ioctl+0x380/0x520
[ 3697.854542] ? __pfx_ksmbd_rpc_ioctl+0x10/0x10
[ 3697.854757] ? kasan_unpoison+0x48/0x70
[ 3697.854962] ? copy_from_kernel_nofault+0x32c/0x4e0
[ 3697.855166] ? kasan_unpoison+0x48/0x70
[ 3697.855416] fsctl_pipe_transceive+0x139/0x7a0
[ 3697.855705] ? __pfx_copy_from_kernel_nofault+0x10/0x10
[ 3697.855937] ? __pfx_fsctl_pipe_transceive+0x10/0x10
[ 3697.856388] ? __sanitizer_cov_trace_switch+0x7b/0x140
[ 3697.856620] smb2_ioctl+0x1141/0x3420
[ 3697.856994] ? __pfx_smb2_ioctl+0x10/0x10
[ 3697.857182] ? get_smb2_cmd_val+0xe3/0x1c0
[ 3697.857655] handle_ksmbd_work+0x9ad/0x15e0
[ 3697.858034] ? __pfx_handle_ksmbd_work+0x10/0x10
[ 3697.858251] ? lock_release+0xf7/0x360
[ 3697.858466] ? process_scheduled_works+0x954/0x1600
[ 3697.858698] ? process_scheduled_works+0x954/0x1600
[ 3697.858905] process_scheduled_works+0xc22/0x1600
[ 3697.859368] ? __pfx_process_scheduled_works+0x10/0x10
[ 3697.859637] ? __pfx_assign_work+0x10/0x10
[ 3697.859896] ? lock_is_held_type+0x7b/0x110
[ 3697.860146] worker_thread+0x975/0xee0
[ 3697.860524] ? __pfx_do_raw_spin_lock+0x10/0x10
[ 3697.860830] ? __kthread_parkme+0x21e/0x260
[ 3697.861105] kthread+0x3a6/0x490
[ 3697.861423] ? __pfx_worker_thread+0x10/0x10
[ 3697.861643] ? __pfx_kthread+0x10/0x10
[ 3697.861878] ret_from_fork+0x55a/0xa20
[ 3697.862194] ? __pfx_ret_from_fork+0x10/0x10
[ 3697.862480] ? __pfx_kthread+0x10/0x10
[ 3697.862714] ret_from_fork_asm+0x1a/0x30
[ 3697.862965] </TASK>
[ 3697.863039]
[ 3697.938882] Allocated by task 20761:
[ 3697.940257] kasan_save_track+0x3e/0x80
[ 3697.941782] __kasan_kmalloc+0x72/0x90
[ 3697.943228] __kvmalloc_node_noprof+0x3e9/0x6a0
[ 3697.944948] handle_generic_event+0x59b/0x750
[ 3697.946592] genl_family_rcv_msg_doit+0x3d6/0x560
[ 3697.946977] genl_rcv_msg+0x67c/0x900
[ 3697.947224] netlink_rcv_skb+0x286/0x580
[ 3697.947488] genl_rcv+0x2d/0x80
[ 3697.947706] netlink_unicast+0x937/0xb70
[ 3697.947993] netlink_sendmsg+0x977/0xc10
[ 3697.948268] __sock_sendmsg+0x264/0x2d0
[ 3697.948536] __sys_sendto+0x4de/0x690
[ 3697.948789] __x64_sys_sendto+0x173/0x380
[ 3697.949069] do_syscall_64+0x13d/0x420
[ 3697.949328] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 3697.949662]
[ 3697.949779] The buggy address belongs to the object at ffff888105f95908
[ 3697.949779] which belongs to the cache kmalloc-8 of size 8
[ 3697.950550] The buggy address is located 0 bytes to the right of
[ 3697.950550] allocated 8-byte region [ffff888105f95908, ffff888105f95910)
[ 3697.951455]
[ 3697.951574] The buggy address belongs to the physical page:
[ 3697.951958] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff888105f951b8 pfn:0x105f95
[ 3697.952571] flags: 0x100000000000200(workingset|node=0|zone=2)
[ 3697.952973] page_type: f5(slab)
[ 3697.953198] raw: 0100000000000200 ffff888100042640 ffffea0004063610 ffff888100040588
[ 3697.953707] raw: ffff888105f951b8 00000000001c000e 00000000f5000000 0000000000000000
[ 3697.954240] page dumped because: kasan: bad access detected
[ 3697.954616]
[ 3697.954734] Memory state around the buggy address:
[ 3697.955063] ffff888105f95800: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fa
[ 3697.955534] ffff888105f95880: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 3697.956006] >ffff888105f95900: fc 00 fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 3697.956477] ^
[ 3697.956728] ffff888105f95980: fc fc fc fa fc fc fc fc fc fc fc fc fc fc fc fc
[ 3697.957202] ffff888105f95a00: fc fc fc fc fc fa fc fc fc fc fc fc fc fc fc fc
[ 3697.957671] ==================================================================
The final "entry->msg_sz != msg_sz" comparison cannot help: the offending
read has already happened by the time it runs. Every case in the switch
shares this pattern.
Floor entry->msg_sz against the base struct of each event type before
dereferencing any of its length fields. On failure ipc_msg_send_request()
already frees the response and returns NULL, so callers stay safe.
The malformed message originates from the ksmbd.mountd daemon over genl
netlink rather than a remote SMB client, so triggering it requires a buggy
or compromised daemon; it is still an out-of-bounds read the validator is
meant to prevent.
Fixes:
|
||
|
|
db82fbe4bb |
smb: smbdirect: release pending child sockets outside the handler lock
smbdirect_socket_destroy() releases the listener's pending/ready child
sockets while still holding the listener's handler lock, the
&id_priv->handler_mutex taken via rdma_lock_handler(), not
sc->listen.lock, and before the listener's own rdma_destroy_id().
That ordering has one real consequence and one cosmetic one.
The real one: smbdirect_socket_release() drops the child's last
reference, which destroys the child's cm_id. Doing that before the
listener's rdma_destroy_id() lets _cma_cancel_listens(), running from
the listener's _destroy_id(), walk an already freed child id_priv,
which KASAN catches as a slab-use-after-free during listener shutdown:
[ 4758.909130] BUG: KASAN: slab-use-after-free in __mutex_lock+0x1469/0x1560
[ 4758.911450] Read of size 1 at addr ffff88821c381db4 by task ksmbd.control/1652
[ 4758.913262] Call Trace:
[ 4758.913267] <TASK>
[ 4758.913299] __mutex_lock+0x1469/0x1560
[ 4758.913408] _cma_cancel_listens+0x312/0x3b0
[ 4758.913413] _destroy_id+0x363/0xee0
[ 4758.913417] smbdirect_socket_destroy_sync+0x17d5/0x2440
[ 4758.913443] smbdirect_socket_release+0x124/0x230
[ 4758.913451] ksmbd_rdma_stop_listening+0x9f/0x190
[ 4758.913457] ksmbd_conn_transport_destroy+0x65/0x3c0
[ 4758.913463] kill_server_store+0x1fb/0x2b0
[ 4758.913501] kernfs_fop_write_iter+0x349/0x4d0
[ 4758.913507] vfs_write+0x5e7/0xc70
[ 4758.913528] ksys_write+0x12a/0x210
[ 4758.913541] do_syscall_64+0x135/0x460
[ 4758.913555] entry_SYSCALL_64_after_hwframe+0x77/0x7f
The cosmetic one: releasing a child recurses into
smbdirect_socket_destroy(), which takes the child's own
rdma_lock_handler() lock nested under the listener's. The listener's
and the child's cm_id are always different instances, so this cannot
deadlock for real; the CM core itself nests a new connection id's
handler_mutex under the listening id's in cma_ib_req_handler(). But
lockdep only sees one lock class, reports possible recursive locking,
and then disables itself, hiding real locking bugs for the rest of the
run:
[ 2424.579653] WARNING: possible recursive locking detected
[ 2424.581180] 7.1.0-next-20260623+ #89 Not tainted
[ 2424.582548] --------------------------------------------
[ 2424.584500] ksmbd.control/8854 is trying to acquire lock:
[ 2424.586817] ffff888102303c20 (&id_priv->handler_mutex){+.+.}-{4:4}, at: smbdirect_socket_destroy_sync+0xc39/0x2440
[ 2424.590590]
[ 2424.590590] but task is already holding lock:
[ 2424.591601] ffff888102046c20 (&id_priv->handler_mutex){+.+.}-{4:4}, at: smbdirect_socket_destroy_sync+0xc39/0x2440
[ 2424.594178]
[ 2424.594178] other info that might help us debug this:
[ 2424.596634] Possible unsafe locking scenario:
[ 2424.596634]
[ 2424.598841] CPU0
[ 2424.599765] ----
[ 2424.600695] lock(&id_priv->handler_mutex);
[ 2424.601836] lock(&id_priv->handler_mutex);
[ 2424.602590]
[ 2424.602590] *** DEADLOCK ***
[ 2424.602590]
[ 2424.604512] May be due to missing lock nesting notation
Splice the pending/ready children onto a local list under the
listener's listen.lock, while the handler lock is held so a concurrent
CM CONNECT_REQUEST cannot add more, but defer the actual
smbdirect_socket_release() calls until after the listener's cm_id has
been destroyed and its handler lock dropped. The children are
independent sockets whose teardown needs neither the listener's
handler lock nor its cm_id.
Found with ksmbdzzer [2], a KSMBD fuzzer that drives libFuzzer with a
kcov-dataflow [1] coverage vector: it folds each instrumented
comparison/argument's runtime operand value together with its PC (the
default arm mixes them as pc⊕val) so that a new operand value at a known
site counts as new coverage.
[1] https://lwn.net/Articles/1077606/
[2] https://github.com/yskzalloc/kcov-dataflow
Fixes:
|
||
|
|
76fa42c004 |
smb: smbdirect: avoid recursive listen.lock during cleanup
__smbdirect_socket_schedule_cleanup() and smbdirect_socket_cleanup_work()
take sc->listen.lock and walk the listener's pending list, recursing
into smbdirect_socket_schedule_cleanup() for each child, and every
child takes its own listen.lock inside that walk.
This cannot deadlock for real: the nesting is strictly listener into
child, a child never listens, so the outer and the inner lock are
always different instances. lockdep only tracks lock classes, though;
it sees the same class acquired twice and reports a possible recursive
locking deadlock. This change therefore works around a lockdep
limitation rather than fixing a real hang, but the report is still
worth avoiding: lockdep disables itself after the first splat and then
hides real locking bugs for the rest of the run.
Only a socket that was a listener owns a populated listen.ready/pending
list; a child has empty lists and nothing to do in these blocks. Guard
both of them with sc->listen.backlog != -1, the "was a listener" marker
that smbdirect_socket_destroy() already uses: listen.backlog leaves its
initial -1 exactly once, when smbdirect_socket_listen() succeeds. The
alternative !sc->accept.listener test reads as "not a listener" while
meaning the opposite, and it is also true for an accepted child, whose
accept.listener has been cleared on hand-over. With the guard the walk
only runs for a listener and never nests a child's listen.lock under
it; a pending child stays on its listener's list for the free path
(smbdirect_socket_destroy) to reap.
[ 741.705044] WARNING: possible recursive locking detected
[ 741.705403] 7.1.0-next-20260623+ #75 Not tainted
[ 741.705695] --------------------------------------------
[ 741.706022] ksmbd.control/18502 is trying to acquire lock:
[ 741.706379] ffff888108d612f8 (&sc->listen.lock){....}-{3:3}, at: __smbdirect_socket_schedule_cleanup+0x719/0xd70
[ 741.707008]
[ 741.707008] but task is already holding lock:
[ 741.707396] ffff8881087642f8 (&sc->listen.lock){....}-{3:3}, at: __smbdirect_socket_schedule_cleanup+0x719/0xd70
[ 741.708025]
[ 741.708025] other info that might help us debug this:
[ 741.708448] Possible unsafe locking scenario:
[ 741.708448]
[ 741.708845] CPU0
[ 741.709016] ----
[ 741.709186] lock(&sc->listen.lock);
[ 741.709453] lock(&sc->listen.lock);
[ 741.709705]
[ 741.709705] *** DEADLOCK ***
[ 741.709705]
[ 741.710095] May be due to missing lock nesting notation
[ 741.710095]
[ 741.710663] 6 locks held by ksmbd.control/18502:
[ 741.710975] #0: ffff888109e51420 (sb_writers#7){.+.+}-{0:0}, at: vfs_write+0x1e7/0xc70
[ 741.711561] #1: ffff888126ec3880 (&of->mutex){+.+.}-{4:4}, at: kernfs_fop_write_iter+0x1be/0x4d0
[ 741.712147] #2: ffff888102af17b0 (kn->active#45){.+.+}-{0:0}, at: kernfs_fop_write_iter+0x205/0x4d0
[ 741.712803] #3: ffffffff85ad1e00 (ctrl_lock){+.+.}-{4:4}, at: kill_server_store+0x1e0/0x2b0
[ 741.713381] #4: ffffffff85ad41a0 (init_lock){+.+.}-{4:4}, at: ksmbd_conn_transport_destroy+0x5b/0x3c0
[ 741.713995] #5: ffff8881087642f8 (&sc->listen.lock){....}-{3:3}, at: __smbdirect_socket_schedule_cleanup+0x719/0xd70
[ 741.714736]
[ 741.714736] stack backtrace:
[ 741.715038] CPU: 4 UID: 0 PID: 18502 Comm: ksmbd.control Not tainted 7.1.0-next-20260623+ #75 PREEMPT(lazy)
[ 741.715043] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
[ 741.715046] Call Trace:
[ 741.715049] <TASK>
[ 741.715052] dump_stack_lvl+0x77/0xa0
[ 741.715058] print_deadlock_bug+0x279/0x290
[ 741.715065] __lock_acquire+0x272a/0x2e30
[ 741.715070] ? stack_trace_save+0xae/0x100
[ 741.715075] ? smb_direct_logging_vaprintf+0x1a0/0x230
[ 741.715079] ? __pfx_smb_direct_logging_vaprintf+0x10/0x10
[ 741.715082] ? __timer_delete+0x58/0x320
[ 741.715087] lock_acquire+0xd3/0x270
[ 741.715091] ? __smbdirect_socket_schedule_cleanup+0x719/0xd70
[ 741.715095] ? entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 741.715099] _raw_spin_lock_irqsave+0x42/0x60
[ 741.715105] ? __smbdirect_socket_schedule_cleanup+0x719/0xd70
Note the two addresses above: ffff888108d612f8 is the child's lock,
ffff8881087642f8 the listener's, always distinct objects.
Found with ksmbdzzer [2], a KSMBD fuzzer that drives libFuzzer with a
kcov-dataflow [1] coverage vector: it folds each instrumented
comparison/argument's runtime operand value together with its PC (the
default arm mixes them as pc⊕val) so that a new operand value at a known
site counts as new coverage.
[1] https://lwn.net/Articles/1077606/
[2] https://github.com/yskzalloc/kcov-dataflow
Fixes:
|
||
|
|
383a9480f5 |
smb: smbdirect: destroy QP before mem pools on accept failure
On the rdma_accept_failed error path of
smbdirect_accept_connect_request(), the receive io posted just above is
owned by the QP (recv_io is set to NULL after a successful post). The
error path fell through to smbdirect_connection_destroy_mem_pools()
before smbdirect_connection_destroy_qp(), so the mem pools and the
recv_io slab cache were destroyed while that recv_io was still
outstanding on the QP.
The drain in smbdirect_connection_destroy_qp() (ib_drain_qp()) is what
runs the recv completion that returns the recv_io to the free list, so
destroying the pools first leaves the object outstanding at
kmem_cache_destroy() time ("Slab cache still has objects") and later
frees it into an already-destroyed mempool (mempool_free_bulk
NULL-pointer dereference).
Give rdma_accept_failed its own teardown that drains the QP first, then
destroys the mem pools, and returns. The remaining labels
(post_recv_io_failed onward) run before the recv_io was ever posted, so
they keep the mem-pools-then-qp order.
The outstanding recv_io at kmem_cache_destroy() time:
[ 3487.344647] =============================================================================
[ 3487.349942] BUG smbdirect_recv_io_cache_ffff88811ba99000 (Not tainted): Objects remaining on __kmem_cache_shutdown()
[ 3487.356078] -----------------------------------------------------------------------------
[ 3487.356078]
[ 3487.356738] Object 0xffff8881511c3440 @offset=13376
[ 3487.358464] Allocated in mempool_alloc_noprof+0x18c/0x290 age=1194 cpu=6 pid=22254
[ 3487.361197] mempool_alloc_noprof+0x18c/0x290
[ 3487.361542] smbdirect_connection_create_mem_pools+0x405/0x780
[ 3487.361972] smbdirect_accept_connect_request+0x5a8/0x1b80
[ 3487.362359] smbdirect_listen_rdma_event_handler+0x1579/0x1b90
[ 3487.362779] cma_cm_event_handler+0x9c/0x230
[ 3487.363096] cma_ib_req_handler+0x2682/0x45d0
[ 3487.363414] cm_process_work+0x56/0x3d0
[ 3487.363676] cm_work_handler+0x8a0e/0xd000
[ 3487.367496] process_scheduled_works+0xa07/0x13a0
[ 3487.367859] worker_thread+0x7c9/0xc80
[ 3487.368148] kthread+0x341/0x430
[ 3487.368407] ret_from_fork+0x3a8/0x7a0
[ 3487.368704] ret_from_fork_asm+0x1a/0x30
[ 3487.370307] Slab 0xffffea0005447000 objects=19 used=1 fp=0xffff8881511c0040 flags=0x100000000000240(workingset|head|node=0|zone=2)
[ 3487.372840] ------------[ cut here ]------------
[ 3487.373195] WARNING: mm/slub.c:1244 at __slab_err+0x1a/0x30, CPU#6: kworker/6:84/22254
[ 3487.373759] Modules linked in:
[ 3487.373993] CPU: 6 UID: 0 PID: 22254 Comm: kworker/6:84 Tainted: G B 7.1.0-next-20260623+ #88 PREEMPT(lazy)
[ 3487.374778] Tainted: [B]=BAD_PAGE
[ 3487.377830] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
[ 3487.378515] Workqueue: ib_cm cm_work_handler
[ 3487.378820] RIP: 0010:__slab_err+0x1a/0x30
[ 3487.379129] Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 0f 1f 44 00 00 e8 36 00 00 00 bf 05 00 00 00 be 01 00 00 00 e8 f7 75 45 00 90 <0f> 0b 90 c3 cc cc cc cc cc 66 66 66 66 2e 0f 1f 84 00 00 00 00 00
[ 3487.383255] RSP: 0018:ffff888220fc7050 EFLAGS: 00010093
[ 3487.383643] RAX: ffffffff8168e60a RBX: ffff88810955e640 RCX: ffff88821c381d80
[ 3487.384158] RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffffffff870fa080
[ 3487.384662] RBP: ffff888220fc7068 R08: ffffffff870fa087 R09: 1ffffffff0e1f410
[ 3487.385192] R10: dffffc0000000000 R11: fffffbfff0e1f411 R12: ffffea0005447210
[ 3487.385674] R13: ffffea0005447000 R14: ffff888220fc7068 R15: ffff88812a8ab300
[ 3487.388932] FS: 0000000000000000(0000) GS:ffff888427e76000(0000) knlGS:0000000000000000
[ 3487.389529] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 3487.389934] CR2: 00007ffcf2d84fd8 CR3: 0000000111d64006 CR4: 0000000000f72ef0
[ 3487.390440] PKRU: 55555554
[ 3487.390641] Call Trace:
[ 3487.390826] <TASK>
[ 3487.391209] __kmem_cache_shutdown+0x1aa/0x2b0
[ 3487.392062] ? smbdirect_connection_destroy_mem_pools+0x239/0x300
[ 3487.393565] kmem_cache_destroy+0x9d/0x180
[ 3487.398663] smbdirect_connection_destroy_mem_pools+0x239/0x300
[ 3487.403534] ? __pfx_smb_direct_logging_needed+0x10/0x10
[ 3487.407562] smbdirect_accept_connect_request+0x95c/0x1b80
[ 3487.412391] ? __pfx_smbdirect_accept_connect_request+0x10/0x10
[ 3487.416753] ? do_raw_spin_lock+0x130/0x300
[ 3487.420623] ? smbdirect_socket_set_initial_parameters+0x28b/0x6a0
[ 3487.424322] ? lock_acquire+0x4c/0x270
[ 3487.424409] ksmbd: can't change a file to a directory
[ 3487.426321] ? trace_irq_enable+0x36/0x120
[ 3487.429144] smbdirect_listen_rdma_event_handler+0x1579/0x1b90
[ 3487.432606] ? __pfx_smbdirect_listen_rdma_event_handler+0x10/0x10
[ 3487.433595] ? trace_cm_event_handler+0x51/0x170
[ 3487.435183] ? __pfx_smbdirect_listen_rdma_event_handler+0x10/0x10
[ 3487.435646] ? cma_listen_handler+0xf6/0x150
[ 3487.435975] cma_cm_event_handler+0x9c/0x230
[ 3487.436288] cma_ib_req_handler+0x2682/0x45d0
[ 3487.439039] ? __pfx_cma_ib_req_handler+0x10/0x10
[ 3487.439540] ? __pfx_roce_resolve_route_from_path+0x10/0x10
[ 3487.439972] ? stack_depot_save_flags+0x34/0x840
[ 3487.440374] ? __xas_nomem+0xa9/0x410
[ 3487.443356] ? xas_clear_mark+0x26c/0x4a0
[ 3487.443673] cm_process_work+0x56/0x3d0
[ 3487.443969] ? _raw_spin_unlock_irq+0x28/0x50
[ 3487.444317] cm_work_handler+0x8a0e/0xd000
[ 3487.444624] ? __pfx_cm_work_handler+0x10/0x10
[ 3487.444971] ? pwq_dec_nr_in_flight+0xa73/0xdf0
[ 3487.445344] ? __pfx_pwq_dec_nr_in_flight+0x10/0x10
[ 3487.445737] ? lock_acquire+0x4c/0x270
[ 3487.448833] ? process_scheduled_works+0x995/0x13a0
[ 3487.449230] ? process_scheduled_works+0x995/0x13a0
[ 3487.449588] process_scheduled_works+0xa07/0x13a0
[ 3487.449938] ? __pfx_process_scheduled_works+0x10/0x10
[ 3487.450334] ? do_raw_spin_lock+0x130/0x300
[ 3487.450639] ? assign_work+0x3bb/0x5c0
[ 3487.450916] worker_thread+0x7c9/0xc80
[ 3487.451211] kthread+0x341/0x430
[ 3487.451453] ? __pfx_worker_thread+0x10/0x10
[ 3487.451756] ? __pfx_kthread+0x10/0x10
[ 3487.454814] ret_from_fork+0x3a8/0x7a0
[ 3487.455114] ? __pfx_ret_from_fork+0x10/0x10
[ 3487.455450] ? __switch_to+0xb76/0x1110
[ 3487.455772] ? __pfx_kthread+0x10/0x10
[ 3487.456081] ret_from_fork_asm+0x1a/0x30
[ 3487.456384] </TASK>
[ 3487.456549] irq event stamp: 0
[ 3487.456767] hardirqs last enabled at (0): [<0000000000000000>] 0x0
[ 3487.460124] hardirqs last disabled at (0): [<ffffffff81684648>] copy_process+0xa08/0x3a10
[ 3487.460726] softirqs last enabled at (0): [<ffffffff81684648>] copy_process+0xa08/0x3a10
[ 3487.461328] softirqs last disabled at (0): [<0000000000000000>] 0x0
[ 3487.461778] ---[ end trace 0000000000000000 ]---
[ 3487.543875] ksmbd: can't change a file to a directory
[ 3487.599675] ksmbd: can't change a file to a directory
[ 3487.626694] ksmbd: can't change a file to a directory
[ 3487.824687] ksmbd: can't change a file to a directory
[ 3487.871840] ksmbd: can't change a file to a directory
[ 3487.986207] ------------[ cut here ]------------
[ 3487.987157] kmem_cache_destroy smbdirect_recv_io_cache_ffff88811ba99000: Slab cache still has objects when called from smbdirect_connection_destroy_mem_pools+0x239/0x300
[ 3487.987183] WARNING: mm/slab_common.c:572 at kmem_cache_destroy+0x15c/0x180, CPU#6: kworker/6:84/22254
[ 3487.999821] Modules linked in:
[ 3488.001902] CPU: 6 UID: 0 PID: 22254 Comm: kworker/6:84 Tainted: G B W 7.1.0-next-20260623+ #88 PREEMPT(lazy)
[ 3488.008289] Tainted: [B]=BAD_PAGE, [W]=WARN
[ 3488.010459] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
[ 3488.014502] Workqueue: ib_cm cm_work_handler
[ 3488.017790] RIP: 0010:kmem_cache_destroy+0x16a/0x180
[ 3488.020662] Code: fd ff 48 8b 3d 2f c0 9c 06 48 89 de 5b 41 5e 5d e9 5b a3 0e 00 48 8d 3d a4 07 12 04 48 8b 53 58 48 c7 c6 91 9d 3e 85 4c 89 f1 <67> 48 0f b9 3a e9 33 ff ff ff 66 66 66 2e 0f 1f 84 00 00 00 00 00
[ 3488.028077] RSP: 0018:ffff888220fc70b8 EFLAGS: 00010202
[ 3488.032038] RAX: 0000000000000001 RBX: ffff88810955e640 RCX: ffffffff822bc079
[ 3488.035742] RDX: ffff88812404ec40 RSI: ffffffff853e9d91 RDI: ffffffff85f7ac50
[ 3488.037830] RBP: 0000000000000001 R08: ffff8883aef3e843 R09: 1ffff11075de7d08
[ 3488.041076] R10: dffffc0000000000 R11: ffffed1075de7d09 R12: 1ffff11024fa6c3c
[ 3488.045376] R13: ffff888127d361e8 R14: ffffffff822bc079 R15: ffff88811ba99538
[ 3488.049073] FS: 0000000000000000(0000) GS:ffff888427e76000(0000) knlGS:0000000000000000
[ 3488.052515] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 3488.054934] CR2: 00007ffcf2d84fd8 CR3: 0000000111d64006 CR4: 0000000000f72ef0
[ 3488.058529] PKRU: 55555554
[ 3488.060542] Call Trace:
[ 3488.061595] <TASK>
[ 3488.062006] smbdirect_connection_destroy_mem_pools+0x239/0x300
[ 3488.066041] ? __pfx_smb_direct_logging_needed+0x10/0x10
[ 3488.068620] smbdirect_accept_connect_request+0x95c/0x1b80
[ 3488.071594] ? __pfx_smbdirect_accept_connect_request+0x10/0x10
[ 3488.073218] ksmbd: not allow base filename in rename
[ 3488.074751] ? do_raw_spin_lock+0x130/0x300
[ 3488.076792] ksmbd: can't change a file to a directory
[ 3488.077942] ? smbdirect_socket_set_initial_parameters+0x28b/0x6a0
[ 3488.080143] ? lock_acquire+0x4c/0x270
[ 3488.080747] ? trace_irq_enable+0x36/0x120
[ 3488.081400] smbdirect_listen_rdma_event_handler+0x1579/0x1b90
[ 3488.085089] ? __pfx_smbdirect_listen_rdma_event_handler+0x10/0x10
[ 3488.089333] ? trace_cm_event_handler+0x51/0x170
[ 3488.092637] ? __pfx_smbdirect_listen_rdma_event_handler+0x10/0x10
[ 3488.095741] ? cma_listen_handler+0xf6/0x150
[ 3488.099638] cma_cm_event_handler+0x9c/0x230
[ 3488.101552] cma_ib_req_handler+0x2682/0x45d0
[ 3488.104571] ? __pfx_cma_ib_req_handler+0x10/0x10
[ 3488.106790] ? __pfx_roce_resolve_route_from_path+0x10/0x10
[ 3488.109799] ? stack_depot_save_flags+0x34/0x840
[ 3488.112174] ? __xas_nomem+0xa9/0x410
[ 3488.114217] ? xas_clear_mark+0x26c/0x4a0
[ 3488.116854] cm_process_work+0x56/0x3d0
[ 3488.118179] ? _raw_spin_unlock_irq+0x28/0x50
[ 3488.120034] cm_work_handler+0x8a0e/0xd000
[ 3488.121677] ? __pfx_cm_work_handler+0x10/0x10
[ 3488.123682] ? pwq_dec_nr_in_flight+0xa73/0xdf0
[ 3488.126928] ? __pfx_pwq_dec_nr_in_flight+0x10/0x10
[ 3488.129390] ? lock_acquire+0x4c/0x270
[ 3488.131432] ? process_scheduled_works+0x995/0x13a0
[ 3488.132694] ksmbd: can't change a file to a directory
[ 3488.136702] ? process_scheduled_works+0x995/0x13a0
[ 3488.140060] process_scheduled_works+0xa07/0x13a0
[ 3488.143379] ? __pfx_process_scheduled_works+0x10/0x10
[ 3488.147221] ? do_raw_spin_lock+0x130/0x300
[ 3488.150790] ? assign_work+0x3bb/0x5c0
[ 3488.154259] worker_thread+0x7c9/0xc80
[ 3488.155730] kthread+0x341/0x430
[ 3488.158309] ? __pfx_worker_thread+0x10/0x10
[ 3488.160865] ? __pfx_kthread+0x10/0x10
[ 3488.164384] ret_from_fork+0x3a8/0x7a0
[ 3488.167020] ? __pfx_ret_from_fork+0x10/0x10
[ 3488.170050] ? __switch_to+0xb76/0x1110
[ 3488.171809] ? __pfx_kthread+0x10/0x10
[ 3488.174955] ret_from_fork_asm+0x1a/0x30
[ 3488.175605] </TASK>
[ 3488.176206] irq event stamp: 0
[ 3488.179360] hardirqs last enabled at (0): [<0000000000000000>] 0x0
[ 3488.186521] hardirqs last disabled at (0): [<ffffffff81684648>] copy_process+0xa08/0x3a10
[ 3488.191889] softirqs last enabled at (0): [<ffffffff81684648>] copy_process+0xa08/0x3a10
[ 3488.196853] softirqs last disabled at (0): [<0000000000000000>] 0x0
[ 3488.200870] ---[ end trace 0000000000000000 ]---
Found with ksmbdzzer [2], a KSMBD fuzzer that drives libFuzzer with a
kcov-dataflow [1] coverage vector: it folds each instrumented
comparison/argument's runtime operand value together with its PC (the
default arm mixes them as pc⊕val) so that a new operand value at a known
site counts as new coverage.
[1] https://lwn.net/Articles/1077606/
[2] https://github.com/yskzalloc/kcov-dataflow
Fixes:
|
||
|
|
fe2c0cacbc |
smb: smbdirect: free completion queues with ib_free_cq()
smbdirect_connection_destroy_qp() creates the send and receive completion
queues with ib_alloc_cq_any(), which for IB_POLL_WORKQUEUE arms an
internal completion handler that runs ib_cq_poll_work() on a workqueue.
Tearing those CQs down with ib_destroy_cq() frees them without first
cancelling that poll work.
If the provider posts a completion late -- for example Soft-RoCE (rxe)
posting an RNR error from rxe_receiver() after rdma_destroy_qp() -- the
handler re-queues ib_cq_poll_work() on the already-freed CQ, and a
follow-on access faults in rxe_req_notify_cq().
Use ib_free_cq(), which cancel_work_sync()es the poll work before freeing
the CQ, so no completion handler can run against a freed queue.
[ 1236.599526] ==================================================================
[ 1236.602142] BUG: KASAN: slab-use-after-free in ib_cq_poll_work+0xd0/0x1a0
[ 1236.605524] Read of size 8 at addr ffff888111865800 by task kworker/4:1H/82
[ 1236.609017]
[ 1236.609270] CPU: 4 UID: 0 PID: 82 Comm: kworker/4:1H Not tainted 7.2.0-rc3-next-20260717-virtme #110 PREEMPT(lazy)
[ 1236.609287] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
[ 1236.609498] Workqueue: ib-comp-wq ib_cq_poll_work
[ 1236.609525] Call Trace:
[ 1236.609536] <TASK>
[ 1236.609545] __dump_stack+0x21/0x60
[ 1236.609562] dump_stack_lvl+0xc2/0x100
[ 1236.609573] print_address_description+0x77/0x200
[ 1236.609587] ? ib_cq_poll_work+0xd0/0x1a0
[ 1236.609597] print_report+0x58/0x70
[ 1236.609607] kasan_report+0x117/0x150
[ 1236.609623] ? ib_cq_poll_work+0xd0/0x1a0
[ 1236.609636] ? process_scheduled_works+0x954/0x1600
[ 1236.609650] ib_cq_poll_work+0xd0/0x1a0
[ 1236.609662] ? process_scheduled_works+0x954/0x1600
[ 1236.609674] process_scheduled_works+0xc22/0x1600
[ 1236.609698] ? __pfx_process_scheduled_works+0x10/0x10
[ 1236.609713] ? __pfx_assign_work+0x10/0x10
[ 1236.609726] ? lock_is_held_type+0x7b/0x110
[ 1236.609741] worker_thread+0x975/0xee0
[ 1236.609757] ? __pfx_do_raw_spin_lock+0x10/0x10
[ 1236.609775] ? __kthread_parkme+0x21e/0x260
[ 1236.609789] kthread+0x3a6/0x490
[ 1236.609800] ? __pfx_worker_thread+0x10/0x10
[ 1236.609809] ? __pfx_kthread+0x10/0x10
[ 1236.609820] ret_from_fork+0x55a/0xa20
[ 1236.609835] ? __pfx_ret_from_fork+0x10/0x10
[ 1236.609850] ? __pfx_kthread+0x10/0x10
[ 1236.609861] ret_from_fork_asm+0x1a/0x30
[ 1236.609880] </TASK>
[ 1236.609886]
[ 1236.661292] Allocated by task 5076:
[ 1236.662640] kasan_save_track+0x3e/0x80
[ 1236.663842] __kasan_kmalloc+0x72/0x90
[ 1236.664763] __kmalloc_noprof+0x2b0/0x5d0
[ 1236.665356] __ib_alloc_cq+0x284/0x1000
[ 1236.666573] __ib_alloc_cq_any+0x23e/0x340
[ 1236.668654] smbdirect_connection_create_qp+0x6f7/0x1070
[ 1236.669757] smbdirect_accept_connect_request+0x500/0x1ca0
[ 1236.672625] smbdirect_listen_rdma_event_handler+0x1655/0x1c50
[ 1236.673930] cma_listen_handler+0x1bf/0x260
[ 1236.674923] cma_cm_event_handler+0x128/0x380
[ 1236.676926] cma_ib_req_handler+0x2d3d/0x4de0
[ 1236.678368] cm_process_work+0xb0/0x530
[ 1236.680454] cm_queue_work_unlock+0xb1/0x230
[ 1236.681673] cm_work_handler+0x969f/0xdca0
[ 1236.682704] process_scheduled_works+0xc22/0x1600
[ 1236.683447] worker_thread+0x975/0xee0
[ 1236.685901] kthread+0x3a6/0x490
[ 1236.688164] ret_from_fork+0x55a/0xa20
[ 1236.689522] ret_from_fork_asm+0x1a/0x30
[ 1236.690073]
[ 1236.690378] Freed by task 5137:
[ 1236.692242] kasan_save_track+0x3e/0x80
[ 1236.694272] kasan_save_free_info+0x40/0x50
[ 1236.695514] __kasan_slab_free+0x3a/0x60
[ 1236.696773] kfree+0x14e/0x4e0
[ 1236.697216] ib_destroy_cq_user+0x18d/0x250
[ 1236.699817] smbdirect_connection_destroy_qp+0xf2/0x280
[ 1236.702115] smbdirect_socket_destroy_sync+0x1607/0x2720
[ 1236.704062] smbdirect_socket_release+0x140/0x280
[ 1236.705286] smb_direct_free_transport+0x3b/0x90
[ 1236.707241] __ksmbd_conn_release_work+0x99/0xf0
[ 1236.709287] process_scheduled_works+0xc22/0x1600
[ 1236.710763] worker_thread+0x975/0xee0
[ 1236.711262] kthread+0x3a6/0x490
[ 1236.711720] ret_from_fork+0x55a/0xa20
[ 1236.712232] ret_from_fork_asm+0x1a/0x30
[ 1236.712762]
[ 1236.712992] Last potentially related work creation:
[ 1236.715157] kasan_save_stack+0x3e/0x60
[ 1236.716993] kasan_record_aux_stack+0x99/0xb0
[ 1236.718864] insert_work+0xb2/0x4a0
[ 1236.720916] __queue_work+0xebb/0x1260
[ 1236.722397] queue_work_on+0x23b/0x350
[ 1236.723809] ib_cq_completion_workqueue+0xac/0x160
[ 1236.724895] rxe_cq_post+0x433/0x7c0
[ 1236.726273] rxe_receiver+0xa41/0xd0d0
[ 1236.727754] do_work+0x272/0x860
[ 1236.728896] process_scheduled_works+0xc22/0x1600
[ 1236.730026] worker_thread+0x975/0xee0
[ 1236.731499] kthread+0x3a6/0x490
[ 1236.732132] ret_from_fork+0x55a/0xa20
[ 1236.733171] ret_from_fork_asm+0x1a/0x30
[ 1236.734224]
[ 1236.734871] Second to last potentially related work creation:
[ 1236.736001] kasan_save_stack+0x3e/0x60
[ 1236.737161] kasan_record_aux_stack+0x99/0xb0
[ 1236.739074] insert_work+0xb2/0x4a0
[ 1236.740414] __queue_work+0xebb/0x1260
[ 1236.740932] queue_work_on+0x23b/0x350
[ 1236.741849] ib_cq_completion_workqueue+0xac/0x160
[ 1236.744099] rxe_cq_post+0x433/0x7c0
[ 1236.745514] rxe_receiver+0xa41/0xd0d0
[ 1236.746091] do_work+0x272/0x860
[ 1236.747187] process_scheduled_works+0xc22/0x1600
[ 1236.749060] worker_thread+0x975/0xee0
[ 1236.750224] kthread+0x3a6/0x490
[ 1236.751480] ret_from_fork+0x55a/0xa20
[ 1236.751989] ret_from_fork_asm+0x1a/0x30
[ 1236.752974]
[ 1236.753627] The buggy address belongs to the object at ffff888111865800
[ 1236.753627] which belongs to the cache kmalloc-1k of size 1024
[ 1236.757729] The buggy address is located 0 bytes inside of
[ 1236.757729] freed 1024-byte region [ffff888111865800, ffff888111865c00)
[ 1236.760816]
[ 1236.761373] The buggy address belongs to the physical page:
[ 1236.762599] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x111860
[ 1236.764306] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
[ 1236.765281] flags: 0x100000000000040(head|node=0|zone=2)
[ 1236.765979] page_type: f5(slab)
[ 1236.766410] raw: 0100000000000040 ffff8881000430c0 ffffea0004a7e210 ffffea0004586210
[ 1236.770418] raw: 0000000000000000 00000000000a000a 00000000f5000000 0000000000000000
[ 1236.775899] head: 0100000000000040 ffff8881000430c0 ffffea0004a7e210 ffffea0004586210
[ 1236.782823] head: 0000000000000000 00000000000a000a 00000000f5000000 0000000000000000
[ 1236.786239] head: 0100000000000003 fffffffffffffe01 00000000ffffffff 00000000ffffffff
[ 1236.790658] head: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
[ 1236.794132] page dumped because: kasan: bad access detected
[ 1236.798301]
[ 1236.799640] Memory state around the buggy address:
[ 1236.802028] ffff888111865700: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 1236.806254] ffff888111865780: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 1236.809036] >ffff888111865800: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 1236.813968] ^
[ 1236.816416] ffff888111865880: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 1236.819454] ffff888111865900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 1236.823143] ==================================================================
[ 1236.830365] Disabling lock debugging due to kernel taint
[ 1236.831136] BUG: unable to handle page fault for address: ffffc90006dc8080
[ 1236.838157] #PF: supervisor read access in kernel mode
[ 1236.843686] #PF: error_code(0x0000) - not-present page
[ 1236.849393] PGD 100000067 P4D 100000067 PUD 100366067 PMD 12913e067 PTE 0
[ 1236.854156] Oops: Oops: 0000 [#1] SMP KASAN NOPTI
[ 1236.857893] CPU: 4 UID: 0 PID: 82 Comm: kworker/4:1H Tainted: G B 7.2.0-rc3-next-20260717-virtme #110 PREEMPT(lazy)
[ 1236.860893] ksmbd: smb_direct: smbdirect_connection_recv_io_refill() failed -ECONNRESET
[ 1236.864209] Tainted: [B]=BAD_PAGE
[ 1236.864220] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
[ 1236.864233] Workqueue: ib-comp-wq ib_cq_poll_work
[ 1236.878314] RIP: 0010:rxe_req_notify_cq+0x13a/0x350
[ 1236.881683] Code: 20 87 fd 4c 89 fe 48 ba 00 00 00 00 00 fc ff df 4c 8b 3e 49 83 ef 80 4c 89 f8 48 c1 e8 03 0f b6 04 10 84 c0 0f 85 9b 01 00 00 <45> 8b 2f 41 80 3c 16 00 74 18 49 89 f6 48 89 f7 e8 71 20 87 fd 4c
[ 1236.886819] ksmbd: smb_direct: smbdirect_connection_recv_io_refill() failed -ECONNRESET
[ 1236.890671] RSP: 0018:ffff88810222f920 EFLAGS: 00010046
[ 1236.890705] RAX: 0000000000000000 RBX: ffff88810222f920 RCX: ffffffff84c92863
[ 1236.901613] RDX: dffffc0000000000 RSI: ffff888120456d48 RDI: ffff888120456d48
[ 1236.903979] RBP: ffff88810222fa20 R08: 0000000000000003 R09: 0000000000000004
[ 1236.908958] R10: dffffc0000000000 R11: ffffed1020445f10 R12: ffff888120456d40
[ 1236.914473] R13: dffffc0000000000 R14: 1ffff1102408ada9 R15: ffffc90006dc8080
[ 1236.918946] FS: 0000000000000000(0000) GS:ffff88842600d000(0000) knlGS:0000000000000000
[ 1236.921600] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1236.925779] CR2: ffffc90006dc8080 CR3: 000000012b35f003 CR4: 0000000000f72ef0
[ 1236.926809] ksmbd: smb_direct: smbdirect_connection_recv_io_refill() failed -ECONNRESET
[ 1236.928302] PKRU: 55555554
[ 1236.928328] Call Trace:
[ 1236.928338] <TASK>
[ 1236.928352] ? ib_cq_poll_work+0xd0/0x1a0
[ 1236.928374] ? __pfx_rxe_req_notify_cq+0x10/0x10
[ 1236.941601] ? ib_cq_poll_work+0xd0/0x1a0
[ 1236.943306] ib_cq_poll_work+0xfe/0x1a0
[ 1236.943961] ? process_scheduled_works+0x954/0x1600
[ 1236.947036] process_scheduled_works+0xc22/0x1600
[ 1236.951626] ? __pfx_process_scheduled_works+0x10/0x10
[ 1236.954316] ? __pfx_assign_work+0x10/0x10
[ 1236.958110] ? lock_is_held_type+0x7b/0x110
[ 1236.960042] worker_thread+0x975/0xee0
[ 1236.962668] ? __pfx_do_raw_spin_lock+0x10/0x10
[ 1236.965334] ? __kthread_parkme+0x21e/0x260
[ 1236.966058] kthread+0x3a6/0x490
[ 1236.968115] ? __pfx_worker_thread+0x10/0x10
[ 1236.971020] ? __pfx_kthread+0x10/0x10
[ 1236.974488] ret_from_fork+0x55a/0xa20
[ 1236.977419] ? __pfx_ret_from_fork+0x10/0x10
[ 1236.979846] ? __pfx_kthread+0x10/0x10
[ 1236.981238] ret_from_fork_asm+0x1a/0x30
[ 1236.984086] </TASK>
[ 1236.986181] Modules linked in:
[ 1236.989048] CR2: ffffc90006dc8080
[ 1236.990412] ---[ end trace 0000000000000000 ]---
[ 1236.994119] RIP: 0010:rxe_req_notify_cq+0x13a/0x350
[ 1236.998482] Code: 20 87 fd 4c 89 fe 48 ba 00 00 00 00 00 fc ff df 4c 8b 3e 49 83 ef 80 4c 89 f8 48 c1 e8 03 0f b6 04 10 84 c0 0f 85 9b 01 00 00 <45> 8b 2f 41 80 3c 16 00 74 18 49 89 f6 48 89 f7 e8 71 20 87 fd 4c
[ 1237.006635] RSP: 0018:ffff88810222f920 EFLAGS: 00010046
[ 1237.008513] RAX: 0000000000000000 RBX: ffff88810222f920 RCX: ffffffff84c92863
[ 1237.014100] RDX: dffffc0000000000 RSI: ffff888120456d48 RDI: ffff888120456d48
[ 1237.021058] RBP: ffff88810222fa20 R08: 0000000000000003 R09: 0000000000000004
[ 1237.024939] R10: dffffc0000000000 R11: ffffed1020445f10 R12: ffff888120456d40
[ 1237.030203] R13: dffffc0000000000 R14: 1ffff1102408ada9 R15: ffffc90006dc8080
[ 1237.034299] FS: 0000000000000000(0000) GS:ffff88842600d000(0000) knlGS:0000000000000000
[ 1237.037311] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1237.042838] CR2: ffffc90006dc8080 CR3: 000000012b35f003 CR4: 0000000000f72ef0
Found with ksmbdzzer [2], a KSMBD fuzzer that drives libFuzzer with a
kcov-dataflow [1] coverage vector: it folds each instrumented
comparison/argument's runtime operand value together with its PC (the
default arm mixes them as pc⊕val) so that a new operand value at a known
site counts as new coverage.
[1] https://lwn.net/Articles/1077606/
[2] https://github.com/yskzalloc/kcov-dataflow
Fixes:
|
||
|
|
7405d0ba29 |
ksmbd: fix slab-out-of-bounds read in ksmbd_alloc_user()
ksmbd_alloc_user() copies resp->hash_sz bytes out of the mountd IPC
login response with
user->passkey_sz = resp->hash_sz;
user->passkey = kmalloc(resp->hash_sz, KSMBD_DEFAULT_GFP);
if (user->passkey)
memcpy(user->passkey, resp->hash, resp->hash_sz);
resp->hash_sz is a __u16 supplied by the response, but resp->hash[] is
only KSMBD_REQ_MAX_HASH_SZ bytes. A malformed or malicious login
response can set hash_sz well beyond that (up to 65535), so the memcpy()
reads past the end of the response object. ipc_validate_msg() does not
bound hash_sz, so reject any response whose hash_sz exceeds the on-stack
hash[] buffer before allocating and copying.
[ 2030.238706] BUG: KASAN: slab-out-of-bounds in ksmbd_alloc_user+0x278/0x680
[ 2030.240549] Read of size 65535 at addr ffff888121bb6680 by task kworker/4:1/18611
[ 2030.242296]
[ 2030.242710] CPU: 4 UID: 0 PID: 18611 Comm: kworker/4:1 Not tainted 7.1.0-next-20260623-virtme #96 PREEMPT(lazy)
[ 2030.242732] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
[ 2030.242743] Workqueue: ksmbd-io handle_ksmbd_work
[ 2030.242763] Call Trace:
[ 2030.242769] <TASK>
[ 2030.242776] dump_stack_lvl+0xa2/0xd0
[ 2030.242794] print_address_description+0x77/0x200
[ 2030.242815] ? ksmbd_alloc_user+0x278/0x680
[ 2030.242831] print_report+0x58/0x70
[ 2030.242848] kasan_report+0x117/0x150
[ 2030.242869] ? ksmbd_alloc_user+0x278/0x680
[ 2030.242888] kasan_check_range+0x3c7/0x3f0
[ 2030.242908] ? ksmbd_alloc_user+0x278/0x680
[ 2030.242925] __asan_memcpy+0x29/0x70
[ 2030.242942] ksmbd_alloc_user+0x278/0x680
[ 2030.242960] ksmbd_login_user+0xc3/0x120
[ 2030.242978] ntlm_authenticate+0x5e6/0x1b00
[ 2030.243017] ? __pfx_ntlm_authenticate+0x10/0x10
[ 2030.243035] ? ksmbd_session_lookup+0x188/0x1d0
[ 2030.243054] ? __pfx_ksmbd_session_lookup+0x10/0x10
[ 2030.243090] ? __sanitizer_cov_trace_switch+0x7b/0x140
[ 2030.243108] smb2_sess_setup+0x1e4a/0x27b0
[ 2030.243126] ? copy_from_kernel_nofault+0x199/0x300
[ 2030.243156] ? __pfx_smb2_sess_setup+0x10/0x10
[ 2030.243173] ? get_smb2_cmd_val+0xe3/0x1c0
[ 2030.243208] handle_ksmbd_work+0x954/0x1280
[ 2030.243230] ? __pfx_handle_ksmbd_work+0x10/0x10
[ 2030.243249] ? process_scheduled_works+0xa07/0x1490
[ 2030.243270] ? process_scheduled_works+0xa07/0x1490
[ 2030.243291] process_scheduled_works+0xa70/0x1490
[ 2030.243320] ? __pfx_process_scheduled_works+0x10/0x10
[ 2030.243340] ? do_raw_spin_lock+0x130/0x300
[ 2030.243358] ? lock_is_held_type+0x7b/0x110
[ 2030.243388] worker_thread+0x932/0xe20
[ 2030.243415] kthread+0x38a/0x470
[ 2030.243431] ? __pfx_worker_thread+0x10/0x10
[ 2030.243451] ? __pfx_kthread+0x10/0x10
[ 2030.243467] ret_from_fork+0x484/0x910
[ 2030.243485] ? __pfx_ret_from_fork+0x10/0x10
[ 2030.243501] ? __switch_to+0xc77/0x12c0
[ 2030.243523] ? __pfx_kthread+0x10/0x10
[ 2030.243540] ret_from_fork_asm+0x1a/0x30
[ 2030.243564] </TASK>
[ 2030.243570]
[ 2030.290164] Allocated by task 19279:
[ 2030.290911] kasan_save_track+0x3e/0x80
[ 2030.292179] __kasan_kmalloc+0x72/0x90
[ 2030.293217] __kvmalloc_node_noprof+0x3ff/0x6b0
[ 2030.294467] handle_generic_event+0x59b/0x750
[ 2030.295345] genl_family_rcv_msg_doit+0x238/0x340
[ 2030.296553] genl_rcv_msg+0x606/0x7b0
[ 2030.297129] netlink_rcv_skb+0x22b/0x4a0
[ 2030.298500] genl_rcv+0x2d/0x40
[ 2030.299273] netlink_unicast+0x7ba/0x930
[ 2030.300019] netlink_sendmsg+0x8c3/0xb00
[ 2030.301073] __sock_sendmsg+0xec/0x140
[ 2030.301579] __sys_sendto+0x357/0x470
[ 2030.302255] __x64_sys_sendto+0xe3/0x100
[ 2030.303425] do_syscall_64+0x135/0x460
[ 2030.304763] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 2030.305594]
[ 2030.305819] The buggy address belongs to the object at ffff888121bb6640
[ 2030.305819] which belongs to the cache kmalloc-192 of size 192
[ 2030.309595] The buggy address is located 64 bytes inside of
[ 2030.309595] allocated 166-byte region [ffff888121bb6640, ffff888121bb66e6)
[ 2030.312484]
[ 2030.312719] The buggy address belongs to the physical page:
[ 2030.314315] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x121bb6
[ 2030.316481] head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
[ 2030.318248] flags: 0x100000000000040(head|node=0|zone=2)
[ 2030.319662] page_type: f5(slab)
[ 2030.320242] raw: 0100000000000040 ffff8881000424c0 ffffea00047c1510 ffff888100040468
[ 2030.321911] raw: 0000000000000000 0000000000150015 00000000f5000000 0000000000000000
[ 2030.324413] head: 0100000000000040 ffff8881000424c0 ffffea00047c1510 ffff888100040468
[ 2030.326150] head: 0000000000000000 0000000000150015 00000000f5000000 0000000000000000
[ 2030.327960] head: 0100000000000001 ffffffffffffff81 00000000ffffffff 00000000ffffffff
[ 2030.329615] head: ffff888121bb7ab0 0000000000000000 00000000ffffffff 0000000000000000
[ 2030.331861] page dumped because: kasan: bad access detected
[ 2030.332946]
[ 2030.333502] Memory state around the buggy address:
[ 2030.334698] ffff888121bb6580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 2030.336475] ffff888121bb6600: fc fc fc fc fc fc fc fc 00 00 00 00 00 00 00 00
[ 2030.338143] >ffff888121bb6680: 00 00 00 00 00 00 00 00 00 00 00 00 06 fc fc fc
[ 2030.339116] ^
[ 2030.341315] ffff888121bb6700: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 2030.342801] ffff888121bb6780: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
[ 2030.344643] ==================================================================
Found with ksmbdzzer [2], a KSMBD fuzzer that drives libFuzzer with a
kcov-dataflow [1] coverage vector: it folds each instrumented
comparison/argument's runtime operand value together with its PC (the
default arm mixes them as pc⊕val) so that a new operand value at a known
site counts as new coverage.
[1] https://lwn.net/Articles/1077606/
[2] https://github.com/yskzalloc/kcov-dataflow
Fixes:
|
||
|
|
fd8c97d7c1 |
ksmbd: implement the command sequence window
ksmbd tracked only credit counts (total_credits/outstanding_credits) and
never validated the MessageId of an incoming request. As a result a
request carrying a MessageId outside the granted range was accepted, a
MessageId could be replayed, and a 64-bit sequence wrap was not detected.
Maintain a command sequence window per connection:
- [seq_low, seq_high) is the range of granted sequence numbers and
seq_bitmap records which of them have been granted but not yet
consumed. The window starts as { 0 } at connection setup.
- smb2_set_rsp_credits() extends seq_high by the number of credits it
grants (setting the corresponding bits), capped so the window never
spans more than KSMBD_CMD_SEQ_WINDOW (== SMB2_MAX_CREDITS) sequence
numbers. This implements the "limit the range of acceptable
sequence numbers" allowance and keeps seq_bitmap usable as a ring.
- smb2_check_sequence_number(), run for every SMB2 request from
ksmbd_smb2_check_message(), verifies that the CreditCharge
consecutive sequence numbers starting at MessageId lie within the
window and have not already been consumed, then removes them and
slides seq_low forward. CANCEL consumes nothing. A violation
(out of window, replay, or wrap) tears the connection down.
The legacy SMB1 multi-protocol negotiate occupies sequence number 0 but
does not pass through ksmbd_smb2_check_message(), so it consumes that
sequence number explicitly; otherwise seq_low would stay pinned at 0
after the upgrade to SMB2 and eventually stall credit grants.
For an in-order client seq_high - seq_low equals total_credits, so the
window-room cap never reduces the number of credits granted. it only
engages for a client that withholds low sequence numbers.
init_smb2_max_credits() now clamps the configured maximum to
SMB2_MAX_CREDITS so the window (and its bitmap) can always represent
every outstanding sequence number.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
|