summaryrefslogtreecommitdiff
path: root/fs
AgeCommit message (Collapse)AuthorFilesLines
13 daysafs: Fix uninit var in afs_alloc_anon_key()David Howells1-1/+2
commit 19eef1d98eeda3745df35839190b7d4a4adea656 upstream. Fix an uninitialised variable (key) in afs_alloc_anon_key() by setting it to cell->anonymous_key. Without this change, the error check may return a false failure with a bad error number. Most of the time this is unlikely to happen because the first encounter with afs_alloc_anon_key() will usually be from (auto)mount, for which all subsequent operations must wait - apart from other (auto)mounts. Once the call->anonymous_key is allocated, all further calls to afs_request_key() will skip the call to afs_alloc_anon_key() for that cell. Fixes: d27c71257825 ("afs: Fix delayed allocation of a cell's anonymous key") Reported-by: Paulo Alcantra <pc@manguebit.org> Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Paulo Alcantara <pc@manguebit.org> cc: Marc Dionne <marc.dionne@auristor.com> cc: syzbot+41c68824eefb67cdf00c@syzkaller.appspotmail.com cc: linux-afs@lists.infradead.org cc: linux-fsdevel@vger.kernel.org Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysafs: handle CB.InitCallBackState3 requests without a server recordNan Li1-0/+5
commit f3cf725cd284b7912d5522babb44721bf38c8887 upstream. The cache manager callback path now attaches the server record to an incoming call through the rxrpc peer's app data. That association is not guaranteed to exist for every callback request, and most callback handlers already tolerate that case. Make CB.InitCallBackState3 follow the same pattern by checking whether a server record was attached before using it. If the peer is not mapped to a server record, trace the request and ignore it, matching the existing behaviour for other unmatched callback requests. This keeps the callback handler consistent with the rest of the cache manager service and avoids depending on peer state that may not be available for a given request. Fixes: 40e8b52fe8c8 ("afs: Use the per-peer app data provided by rxrpc") Cc: stable@kernel.org Reported-by: Yuan Tan <yuantan098@gmail.com> Reported-by: Yifan Wu <yifanwucs@gmail.com> Reported-by: Juefei Pu <tomapufckgml@gmail.com> Reported-by: Xin Liu <bird@lzu.edu.cn> Signed-off-by: Nan Li <tonanli66@gmail.com> Signed-off-by: Ren Wei <n05ec@lzu.edu.cn> Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260622090856.2746629-2-dhowells@redhat.com cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysafs: Fix delayed allocation of a cell's anonymous keyDavid Howells3-43/+49
commit d27c71257825dced46104eefe42e4d9964bd032e upstream. The allocation of a cell's anonymous key is done in a background thread along with other cell setup such as doing a DNS upcall. In the reported bug, this is triggered by afs_parse_source() parsing the device name given to mount() and calling afs_lookup_cell() with the name of the cell. The normal key lookup then tries to use the key description on the anonymous authentication key as the reference for request_key() - but it may not yet be set and so an oops can happen. This has been made more likely to happen by the fix for dynamic lookup failure. Fix this by firstly allocating a reference name and attaching it to the afs_cell record when the record is created. It can share the memory allocation with the cell name (unfortunately it can't just overlap the cell name by prepending it with "afs@" as the cell name already has a '.' prepended for other purposes). This reference name is then passed to request_key(). Secondly, the anon key is now allocated on demand at the point a key is requested in afs_request_key() if it is not already allocated. A mutex is used to prevent multiple allocation for a cell. Thirdly, make afs_request_key_rcu() return NULL if the anonymous key isn't yet allocated (if we need it) and then the caller can return -ECHILD to drop out of RCU-mode and afs_request_key() can be called. Note that the anonymous key is kind of necessary to make the key lookup cache work as that doesn't currently cache a negative lookup, but it's probably worth some investigation to see if NULL can be used instead. Fixes: 330e2c514823 ("afs: Fix dynamic lookup to fail on cell lookup failure") Reported-by: syzbot+41c68824eefb67cdf00c@syzkaller.appspotmail.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/800328.1764325145@warthog.procyon.org.uk cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysafs: Set vllist to NULL if addr parsing failsEdward Adam Davis1-0/+1
commit 8b3c655fa2406b9853138142746a39b7615c54a2 upstream. syzbot reported a bug in in afs_put_vlserverlist. kAFS: bad VL server IP address BUG: unable to handle page fault for address: fffffffffffffffa ... Oops: Oops: 0002 [#1] SMP KASAN PTI ... RIP: 0010:refcount_dec_and_test include/linux/refcount.h:450 [inline] RIP: 0010:afs_put_vlserverlist+0x3a/0x220 fs/afs/vl_list.c:67 ... Call Trace: <TASK> afs_alloc_cell fs/afs/cell.c:218 [inline] afs_lookup_cell+0x12a5/0x1680 fs/afs/cell.c:264 afs_cell_init+0x17a/0x380 fs/afs/cell.c:386 afs_proc_rootcell_write+0x21f/0x290 fs/afs/proc.c:247 proc_simple_write+0x114/0x1b0 fs/proc/generic.c:825 pde_write fs/proc/inode.c:330 [inline] proc_reg_write+0x23d/0x330 fs/proc/inode.c:342 vfs_write+0x25c/0x1180 fs/read_write.c:682 ksys_write+0x12a/0x240 fs/read_write.c:736 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0x260 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Because afs_parse_text_addrs() parses incorrectly, its return value -EINVAL is assigned to vllist, which results in -EINVAL being used as the vllist address when afs_put_vlserverlist() is executed. Set the vllist value to NULL when a parsing error occurs to avoid this issue. Fixes: e2c2cb8ef07a ("afs: Simplify cell record handling") Reported-by: syzbot+5c042fbab0b292c98fc6@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=5c042fbab0b292c98fc6 Tested-by: syzbot+5c042fbab0b292c98fc6@syzkaller.appspotmail.com Signed-off-by: Edward Adam Davis <eadavis@qq.com> Signed-off-by: David Howells <dhowells@redhat.com> Link: https://lore.kernel.org/4119365.1753108011@warthog.procyon.org.uk cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysafs: Fix lack of locking around modifications of net->cells_dyn_inoDavid Howells2-2/+8
[ Upstream commit 55e841836c6f4646490f7b0347192b7a92d431ba ] Fix the lack of locking around modifications of net->cells_dyn_ino by taking net->cells_lock exclusively. This also requires to cell to be removed from net->cells_dyn_ino in afs_destroy_cell_work() rather than in afs_cell_destroy() as the latter runs in RCU cleanup context and sleeping locks cannot be taken there. Fixes: 1d0b929fc070 ("afs: Change dynroot to create contents on demand") Closes: https://sashiko.dev/#/patchset/20260618074903.2374756-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260622090856.2746629-19-dhowells@redhat.com cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org> Stable-dep-of: 26f17ce6fa3f ("afs: Fix premature cell exposure through /afs") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysafs: Fix dynamic lookup to fail on cell lookup failureDavid Howells7-18/+86
[ Upstream commit 330e2c514823008b22e6afd2055715bc46dd8d55 ] When a process tries to access an entry in /afs, normally what happens is that an automount dentry is created by ->lookup() and then triggered, which jumps through the ->d_automount() op. Currently, afs_dynroot_lookup() does not do cell DNS lookup, leaving that to afs_d_automount() to perform - however, it is possible to use access() or stat() on the automount point, which will always return successfully, have briefly created an afs_cell record if one did not already exist. This means that something like: test -d "/afs/.west" && echo Directory exists will print "Directory exists" even though no such cell is configured. This breaks the "west" python module available on PIP as it expects this access to fail. Now, it could be possible to make afs_dynroot_lookup() perform the DNS[*] lookup, but that would make "ls --color /afs" do this for each cell in /afs that is listed but not yet probed. kafs-client, probably wrongly, preloads the entire cell database and all the known cells are then listed in /afs - and doing ls /afs would be very, very slow, especially if any cell supplied addresses but was wholly inaccessible. [*] When I say "DNS", actually read getaddrinfo(), which could use any one of a host of mechanisms. Could also use static configuration. To fix this, make the following changes: (1) Create an enum to specify the origination point of a call to afs_lookup_cell() and pass this value into that function in place of the "excl" parameter (which can be derived from it). There are six points of origination: - Cell preload through /proc/net/afs/cells - Root cell config through /proc/net/afs/rootcell - Lookup in dynamic root - Automount trigger - Direct mount with mount() syscall - Alias check where YFS tells us the cell name is different (2) Add an extra state into the afs_cell state machine to indicate a cell that's been initialised, but not yet looked up. This is separate from one that can be considered active and has been looked up at least once. (3) Make afs_lookup_cell() vary its behaviour more, depending on where it was called from: If called from preload or root cell config, DNS lookup will not happen until we definitely want to use the cell (dynroot mount, automount, direct mount or alias check). The cell will appear in /afs but stat() won't trigger DNS lookup. If the cell already exists, dynroot will not wait for the DNS lookup to complete. If the cell did not already exist, dynroot will wait. If called from automount, direct mount or alias check, it will wait for the DNS lookup to complete. (4) Make afs_lookup_cell() return an error if lookup failed in one way or another. We try to return -ENOENT if the DNS says the cell does not exist and -EDESTADDRREQ if we couldn't access the DNS. Reported-by: Markus Suvanto <markus.suvanto@gmail.com> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220685 Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/1784747.1761158912@warthog.procyon.org.uk Fixes: 1d0b929fc070 ("afs: Change dynroot to create contents on demand") Tested-by: Markus Suvanto <markus.suvanto@gmail.com> cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org Signed-off-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysafs: Simplify cell record handlingDavid Howells6-261/+176
[ Upstream commit e2c2cb8ef07affd9f69497ea128fa801240fdf32 ] Simplify afs_cell record handling to avoid very occasional races that cause module removal to hang (it waits for all cell records to be removed). There are two things that particularly contribute to the difficulty: firstly, the code tries to pass a ref on the cell to the cell's maintenance work item (which gets awkward if the work item is already queued); and, secondly, there's an overall cell manager that tries to use just one timer for the entire cell collection (to avoid having loads of timers). However, both of these are probably unnecessarily restrictive. To simplify this, the following changes are made: (1) The cell record collection manager is removed. Each cell record manages itself individually. (2) Each afs_cell is given a second work item (cell->destroyer) that is queued when its refcount reaches zero. This is not done in the context of the putting thread as it might be in an inconvenient place to sleep. (3) Each afs_cell is given its own timer. The timer is used to expire the cell record after a period of unuse if not otherwise pinned and can also be used for other maintenance tasks if necessary (of which there are currently none as DNS refresh is triggered by filesystem operations). (4) The afs_cell manager work item (cell->manager) is no longer given a ref on the cell when queued; rather, the manager must be deleted. This does away with the need to deal with the consequences of losing a race to queue cell->manager. Clean up of extra queuing is deferred to the destroyer. (5) The cell destroyer work item makes sure the cell timer is removed and that the normal cell work is cancelled before farming the actual destruction off to RCU. (6) When a network namespace is destroyed or the kafs module is unloaded, it's now a simple matter of marking the namespace as dead then just waking up all the cell work items. They will then remove and destroy themselves once all remaining activity counts and/or a ref counts are dropped. This makes sure that all server records are dropped first. (7) The cell record state set is reduced to just four states: SETTING_UP, ACTIVE, REMOVING and DEAD. The record persists in the active state even when it's not being used until the time comes to remove it rather than downgrading it to an inactive state from whence it can be restored. This means that the cell still appears in /proc and /afs when not in use until it switches to the REMOVING state - at which point it is removed. Note that the REMOVING state is included so that someone wanting to resurrect the cell record is forced to wait whilst the cell is torn down in that state. Once it's in the DEAD state, it has been removed from net->cells tree and is no longer findable and can be replaced. Signed-off-by: David Howells <dhowells@redhat.com> cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/20250224234154.2014840-16-dhowells@redhat.com/ # v1 Link: https://lore.kernel.org/r/20250310094206.801057-12-dhowells@redhat.com/ # v4 Stable-dep-of: 330e2c514823 ("afs: Fix dynamic lookup to fail on cell lookup failure") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysafs: Fix afs_server ref accountingDavid Howells6-354/+285
[ Upstream commit 4882ba78574e2d8c579658f65f6784b0d139d173 ] The current way that afs_server refs are accounted and cleaned up sometimes cause rmmod to hang when it is waiting for cell records to be removed. The problem is that the cell cleanup might occasionally happen before the server cleanup and then there's nothing that causes the cell to garbage-collect the remaining servers as they become inactive. Partially fix this by: (1) Give each afs_server record its own management timer that rather than relying on the cell manager's central timer to drive each individual cell's maintenance work item to garbage collect servers. This timer is set when afs_unuse_server() reduces a server's activity count to zero and will schedule the server's destroyer work item upon firing. (2) Give each afs_server record its own destroyer work item that removes the record from the cell's database, shuts down the timer, cancels any pending work for itself, sends an RPC to the server to cancel outstanding callbacks. This change, in combination with the timer, obviates the need to try and coordinate so closely between the cell record and a bunch of other server records to try and tear everything down in a coordinated fashion. With this, the cell record is pinned until the server RCU is complete and namespace/module removal will wait until all the cell records are removed. (3) Now that incoming calls are mapped to servers (and thus cells) using data attached to an rxrpc_peer, the UUID-to-server mapping tree is moved from the namespace to the cell (cell->fs_servers). This means there can no longer be duplicates therein - and that allows the mapping tree to be simpler as there doesn't need to be a chain of same-UUID servers that are in different cells. (4) The lock protecting the UUID mapping tree is switched to an rw_semaphore on the cell rather than a seqlock on the namespace as it's now only used during mounting in contexts in which we're allowed to sleep. (5) When it comes time for a cell that is being removed to purge its set of servers, it just needs to iterate over them and wake them up. Once a server becomes inactive, its destroyer work item will observe the state of the cell and immediately remove that record. (6) When a server record is removed, it is marked AFS_SERVER_FL_EXPIRED to prevent reattempts at removal. The record will be dispatched to RCU for destruction once its refcount reaches 0. (7) The AFS_SERVER_FL_UNCREATED/CREATING flags are used to synchronise simultaneous creation attempts. If one attempt fails, it will abandon the attempt and allow another to try again. Note that the record can't just be abandoned when dead as it's bound into a server list attached to a volume and only subject to replacement if the server list obtained for the volume from the VLDB changes. Signed-off-by: David Howells <dhowells@redhat.com> cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/20250224234154.2014840-15-dhowells@redhat.com/ # v1 Link: https://lore.kernel.org/r/20250310094206.801057-11-dhowells@redhat.com/ # v4 Stable-dep-of: 330e2c514823 ("afs: Fix dynamic lookup to fail on cell lookup failure") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysafs: Use the per-peer app data provided by rxrpcDavid Howells7-118/+122
[ Upstream commit 40e8b52fe8c8ab6920ea5f59c5469b6918cce624 ] Make use of the per-peer application data that rxrpc now allows the application to store on the rxrpc_peer struct to hold a back pointer to the afs_server record that peer represents an endpoint for. Then, when a call comes in to the AFS cache manager, this can be used to map it to the correct server record rather than having to use a UUID-to-server mapping table and having to do an additional lookup. Signed-off-by: David Howells <dhowells@redhat.com> cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/20250224234154.2014840-14-dhowells@redhat.com/ # v1 Link: https://lore.kernel.org/r/20250310094206.801057-10-dhowells@redhat.com/ # v4 Stable-dep-of: 330e2c514823 ("afs: Fix dynamic lookup to fail on cell lookup failure") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysafs: Drop the net parameter from afs_unuse_cell()David Howells7-18/+17
[ Upstream commit 469c82b558628482002e4819d35b7670f0a989fd ] Remove the redundant net parameter to afs_unuse_cell() as cell->net can be used instead. Signed-off-by: David Howells <dhowells@redhat.com> cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/20250224234154.2014840-12-dhowells@redhat.com/ # v1 Link: https://lore.kernel.org/r/20250310094206.801057-8-dhowells@redhat.com/ # v4 Stable-dep-of: 330e2c514823 ("afs: Fix dynamic lookup to fail on cell lookup failure") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysafs: Make afs_lookup_cell() take a trace noteDavid Howells7-12/+22
[ Upstream commit 92c48157ade88e7a543a64af4a806613fbde2ef3 ] Pass a note to be added to the afs_cell tracepoint to afs_lookup_cell() so that different callers can be distinguished. Signed-off-by: David Howells <dhowells@redhat.com> cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/20250224234154.2014840-11-dhowells@redhat.com/ # v1 Link: https://lore.kernel.org/r/20250310094206.801057-7-dhowells@redhat.com/ # v4 Stable-dep-of: 330e2c514823 ("afs: Fix dynamic lookup to fail on cell lookup failure") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysafs: Improve server refcount/active count tracingDavid Howells4-10/+11
[ Upstream commit 76daa300d41acc1180f8a46eead36905054beafb ] Improve server refcount/active count tracing to distinguish between simply getting/putting a ref and using/unusing the server record (which changes the activity count as well as the refcount). This makes it a bit easier to work out what's going on. Signed-off-by: David Howells <dhowells@redhat.com> cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/20250224234154.2014840-10-dhowells@redhat.com/ # v1 Link: https://lore.kernel.org/r/20250310094206.801057-6-dhowells@redhat.com/ # v4 Stable-dep-of: 330e2c514823 ("afs: Fix dynamic lookup to fail on cell lookup failure") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysovl: use linked upper dentry in copy-up tmpfileSouvik Banerjee1-2/+10
[ Upstream commit e348eecd4d8fa8d18a5157ff59f7be1dc59c5928 ] ovl_copy_up_tmpfile() stores the disconnected O_TMPFILE dentry as the overlay's upper dentry reference via ovl_inode_update(). vfs_tmpfile() allocated this dentry via d_alloc(parentpath->dentry, &slash_name), so d_name is "/" and d_parent is c->workdir. Local upper filesystems (ext4, btrfs, xfs, ...) immediately rename it to "#<inum>" via d_mark_tmpfile() inside their ->tmpfile() op; FUSE and virtiofs do not, so both fields stay that way. Neither identifies the destination directory and filename where ovl_do_link() actually linked the file. When the upper filesystem implements ->d_revalidate() (e.g. FUSE or virtiofs), ovl_revalidate_real() calls it with the dentry's parent inode and a snapshot of d_name. The server tries to look up "/" inside c->workdir, fails, and overlayfs reports -ESTALE. This causes persistent ESTALE errors for any file that was copied up via the tmpfile path, breaking dpkg, apt, and other tools that do rename-over-existing on overlayfs with a FUSE/virtiofs upper. Before commit 6b52243f633e ("ovl: fold copy-up helpers into callers"), the tmpfile copy-up path used a dedicated helper ovl_link_tmpfile() that captured the linked destination dentry returned by ovl_do_link(): err = ovl_do_link(temp, udir, upper); ... if (!err) *newdentry = dget(upper); and published it via ovl_inode_update(d_inode(c->dentry), newdentry). The fold inlined ovl_do_link() into ovl_copy_up_tmpfile() but dropped the dget(upper) capture, and rewrote the publish line as ovl_inode_update(d_inode(c->dentry), dget(temp)) — where temp is the disconnected O_TMPFILE dentry. Fix by keeping a reference to the linked destination dentry after ovl_do_link() succeeds, and publishing that dentry at the existing ovl_inode_update() call site. The non-tmpfile/workdir path continues to publish the renamed temporary dentry. Reproducer: - Mount overlayfs with virtiofs (or a FUSE fs whose server advertises FUSE_TMPFILE) as upper - Run: dpkg -i <any .deb> - Observe: "error installing new file '...': Stale file handle" Fixes: 6b52243f633e ("ovl: fold copy-up helpers into callers") Cc: stable@vger.kernel.org # v4.20+ Signed-off-by: Souvik Banerjee <souvik@amlalabs.com> Link: https://patch.msgid.link/20260501232735.2610824-1-souvik@amlalabs.com Reviewed-by: Amir Goldstein <amir73il@gmail.com> Reviewed-by: Miklos Szeredi <mszeredi@redhat.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org> [ adapted scoped credential and creation helpers to explicit credential, locking, lookup, and cleanup handling ] Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysNFSD: pass nfsd_file to nfsd_iter_read()Mike Snitzer3-8/+9
[ Upstream commit 803bc849f0039291f546ba0e2237faebeb5c073e ] Prepare for nfsd_iter_read() to use the DIO alignment stored in nfsd_file by passing the nfsd_file to nfsd_iter_read() rather than just the file which is associaed with the nfsd_file. This means nfsd4_encode_readv() now also needs the nfsd_file rather than the file. Instead of changing the file arg to be the nfsd_file, we discard the file arg as the nfsd_file (and indeed the file) is already available via the "read" argument. Signed-off-by: Mike Snitzer <snitzer@kernel.org> Reviewed-by: Jeff Layton <jlayton@kernel.org> Reviewed-by: NeilBrown <neil@brown.name> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Stable-dep-of: 18c1cc698861 ("SUNRPC: Return an error from xdr_buf_to_bvec() on overflow") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysxfs: don't replace the wrong part of the cow forkDarrick J. Wong2-75/+135
[ Upstream commit a1caeeadbf57ff86dfc3454398c46de86056a74e ] LOLLM points out that xfs_iext_lookup_extent can return a @got where got->br_startoff < startoff. In this case, xrep_cow_replace_range replaces the entire mapping instead of just the part that had been marked bad in the bitmap, but advances the bitmap cursor in xrep_cow_replace by the amount replaced. As a result, we fail to replace the end of the bad range, and replace part of the good range. Fix this by rewriting the replace method to handle replacing the middle of a cow fork mapping. This we do by returning both the current mapping as @got, and the subset of the mapping that we want to replace as @rep, using @rep to store the results of the new allocation, and comparing @rep to @got to figure out the exact transformations needed. Cc: stable@vger.kernel.org # v6.8 Fixes: dbbdbd0086320a ("xfs: repair problems in CoW forks") Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Assisted-by: LOLLM # finding obvious bugs Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysxfs: factor out xfs_attr3_leaf_initLong Li2-0/+25
[ Upstream commit e65bb55d7f8c2041c8fdb73cd29b0b4cad4ed847 ] Factor out wrapper xfs_attr3_leaf_init function, which exported for external use. Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Long Li <leo.lilong@huawei.com> Signed-off-by: Carlos Maiolino <cem@kernel.org> Stable-dep-of: a1caeeadbf57 ("xfs: don't replace the wrong part of the cow fork") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysrxrpc: Pull out certain app callback funcs into an ops tableDavid Howells1-3/+8
[ Upstream commit 23738cc8048322cf324f330cd697380fb3455da5 ] A number of functions separately furnish an AF_RXRPC socket with callback function pointers into a kernel app (such as the AFS filesystem) that is using it. Replace most of these with an ops table for the entire socket. This makes it easier to add more callback functions. Note that the call incoming data processing callback is retaind as that gets set to different things, depending on the type of op. Signed-off-by: David Howells <dhowells@redhat.com> cc: Marc Dionne <marc.dionne@auristor.com> cc: Simon Horman <horms@kernel.org> cc: linux-afs@lists.infradead.org Link: https://patch.msgid.link/20250411095303.2316168-3-dhowells@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Stable-dep-of: dc175389b18c ("rxrpc: serialize kernel accept preallocation with socket teardown") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysVFS/audit: introduce kern_path_parent() for auditNeilBrown1-0/+43
[ Upstream commit 76a53de6f7ff0641570364234fb4489f4d4fc8e9 ] audit_alloc_mark() and audit_get_nd() both need to perform a path lookup getting the parent dentry (which must exist) and the final target (following a LAST_NORM name) which sometimes doesn't need to exist. They don't need the parent to be locked, but use kern_path_locked() or kern_path_locked_negative() anyway. This is somewhat misleading to the casual reader. This patch introduces a more targeted function, kern_path_parent(), which returns not holding locks. On success the "path" will be set to the parent, which must be found, and the return value is the dentry of the target, which might be negative. This will clear the way to rename kern_path_locked() which is otherwise only used to prepare for removing something. It also allows us to remove kern_path_locked_negative(), which is transformed into the new kern_path_parent(). Signed-off-by: NeilBrown <neil@brown.name> Signed-off-by: Christian Brauner <brauner@kernel.org> Stable-dep-of: 81905b5acbe7 ("audit: fix recursive locking deadlock in audit_dupe_exe()") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysfscrypt: Avoid dynamic allocation in fscrypt_get_devices()Eric Biggers2-48/+34
commit 6fe4e4b8259e1330945b5f3c9476e08473b8e0e8 upstream. When a blk_crypto_key starts being used or is evicted, fs/crypto/ calls fscrypt_get_devices() to get the filesystem's list of block devices, then iterates over them and calls blk_crypto_config_supported(), blk_crypto_start_using_key(), or blk_crypto_evict_key() on each one. Currently, the block device pointers are placed in a dynamically allocated array. This dynamic allocation is problematic because: - It can fail, especially at the fscrypt_destroy_inline_crypt_key() call site when it's invoked for inode eviction under direct reclaim. - fscrypt_destroy_inline_crypt_key() doesn't handle the failure. It just zeroizes and frees the blk_crypto_key without calling blk_crypto_evict_key(). That causes a use-after-free. For now, let's fix this in the straightforward and easily-backportable way by switching to an on-stack array. Currently the fscrypt multi-device functionality is used only by f2fs, which has a hardcoded limit of 8 block devices. An on-stack array works fine for that. (Of course, this solution won't scale up to large number of block devices. For that we'd need a different solution, like moving the block device iteration into the filesystem. Or in the case of btrfs, which will only support blk-crypto-fallback, we should make it just call blk-crypto-fallback directly, so the block devices won't be needed.) Fixes: 22e9947a4b2b ("fscrypt: stop holding extra request_queue references") Cc: stable@vger.kernel.org Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20260713023708.9245-1-ebiggers%40kernel.org Reviewed-by: Christoph Hellwig <hch@lst.de> Link: https://patch.msgid.link/20260719055602.78828-1-ebiggers@kernel.org Signed-off-by: Eric Biggers <ebiggers@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysksmbd: validate ACE size against SID sub-authoritiesNamjae Jeon1-3/+10
commit 5152c6d49e3fd4e9f2e857c57527aead752f1f87 upstream. set_ntacl_dacl() validates sid.num_subauth before copying an ACE, but does not verify that the declared ACE size contains all sub-authorities described by that field. An undersized ACE can therefore be copied and later make the POSIX ACL deduplication walk inspect data beyond the copied ACE boundary. The existing initial bound check is also too small. It only ensures that the ACE size field is accessible before set_ntacl_dacl() reads sid.num_subauth farther into the input buffer. Require enough input for the fixed SID header before accessing num_subauth, reject ACEs smaller than that header, and skip ACEs whose declared size cannot contain the complete SID. This makes the validation consistent with the other ACE walk paths. Reported-by: LocalHost <localhost.detect@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Wentao Guan <guanwentao@uniontech.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysksmbd: bound DACL dedup walk to copied ACEsNamjae Jeon1-6/+10
commit 58d97fcd0bf1aee694e244cc28635b9df95b543b upstream. set_ntacl_dacl() can stop copying ACEs before consuming the full input DACL when size accounting overflows. When that happens, num_aces reflects only the ACEs that were actually copied into the output DACL, but set_posix_acl_entries_dacl() still receives nt_num_aces and uses it to walk the existing ACE array during dedup. That makes the dedup walk scan past the copied ACE array and inspect buffer tail that does not contain valid ACEs. Split the two meanings currently carried by the NT ACE count. Pass the number of copied NT ACEs to bound the dedup walk, and preserve the original "input DACL had NT ACEs" state separately for the Everyone/default ACL fallback. This keeps the dedup walk aligned with the ACEs that are actually present in the rebuilt DACL. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Wentao Guan <guanwentao@uniontech.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysksmbd: restore DACL size on check_add_overflow() to avoid malformed ACLWentao Guan1-1/+6
commit bbf0a8e931204ecdab494a88d43b0a24a04285c5 upstream. check_add_overflow() unconditionally writes the truncated sum into *d even on overflow, per its contract in include/linux/overflow.h. The four check_add_overflow() guards in set_posix_acl_entries_dacl() and set_ntacl_dacl() break out of the ACE-building loops on overflow, but the truncated *size is then consumed downstream at the end of set_ntacl_dacl(): pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size); This produces an on-wire NT ACL whose pndacl->size under-reports the bytes actually written by the preceding fill_ace_for_sid()/memcpy() calls, yielding a malformed ACL that can trigger out-of-bounds reads when re-parsed by clients or ksmbd itself. Restore *size to its pre-addition value on each overflow branch (via `*size -= ace_sz` / `size -= nt_ace_size`) so that after the break, *size once again holds the cumulative size of the successfully-written ACEs. The committed ACL is then truncated-but-self-consistent rather than malformed. The ksmbd DACL builders are the only check_add_overflow() sites found where an overflow path breaks out of a loop and the destination value is consumed afterward. The other nearby break-style cases either return -EINVAL on overflow (transport_ipc.c) or break without consuming the overflowed destination value afterward (buildid.c). Fixes: 299f962c0b02 ("ksmbd: use check_add_overflow() to prevent u16 DACL size overflow") Assisted-by: atomcode:glm-5.2 Assisted-by: Codex:gpt-5.5 Cc: stable@vger.kernel.org Signed-off-by: Wentao Guan <guanwentao@uniontech.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysksmbd: validate num_subauth when copying ACE in set_ntacl_daclHaofeng Li1-1/+7
commit 47f0b34f6bc98ed85bfdc293e8f3e432ec24958d upstream. set_ntacl_dacl() copies each ACE from the attacker-controlled stored security descriptor verbatim into the response DACL without checking sid.num_subauth. The ACE bytes (including an unchecked num_subauth) originate from an authenticated SMB2_SET_INFO(SecInfo=DACL) that is stored raw via ksmbd_vfs_set_sd_xattr(); parse_dacl() rejects a bad ACE with `break` rather than an error, so parse_sec_desc() still returns success and the malformed SD reaches the xattr intact. On a subsequent SMB2_QUERY_INFO(SecInfo=DACL) for an inode carrying a POSIX access ACL, build_sec_desc() -> set_ntacl_dacl() -> set_posix_acl_entries_dacl() walks the copied ACEs and reads ntace->sid.sub_auth[ntace->sid.num_subauth - 1] with num_subauth taken straight from the stored SD. Since sub_auth[] is fixed at SID_MAX_SUB_AUTHORITIES (15), a crafted num_subauth (e.g. 255) drives an out-of-bounds heap read of ~1 KB with an offset fully controlled by an authenticated client. The sibling functions already gate this field: parse_dacl() -- num_subauth == 0 || > SID_MAX_SUB_AUTHORITIES parse_sid() -- num_subauth > SID_MAX_SUB_AUTHORITIES smb_copy_sid() -- min_t(u8, num_subauth, SID_MAX_SUB_AUTHORITIES) set_ntacl_dacl() is the lone inconsistent path that omits the check. Add the same num_subauth validation in set_ntacl_dacl() before copying the ACE, matching the gate already enforced by parse_dacl(). Signed-off-by: Haofeng Li <lihaofeng@kylinos.cn> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Suggested-by: Namjae Jeon <linkinjeon@kernel.org> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Wentao Guan <guanwentao@uniontech.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysksmbd: defer destroy_previous_session() until after NTLM authenticationJames Montgomery1-5/+4
commit c74801ee524f477c174a1899782b6c3b6918d407 upstream. In ntlm_authenticate(), destroy_previous_session() is called using a user pointer resolved from the client-supplied NTLM blob username field before the NTLMv2 response is validated. An authenticated attacker can set the NTLM blob username to match a victim account and set PreviousSessionId to the victim's session ID; destroy_previous_session() destroys the victim's session while ksmbd_decode_ntlmssp_auth_blob() subsequently rejects the request with -EPERM. Move destroy_previous_session() and the prev_id assignment to after ksmbd_decode_ntlmssp_auth_blob() returns success and use sess->user rather than the pre-authentication lookup result. This matches the ordering already used by krb5_authenticate(), where destroy_previous_session() is called only after ksmbd_krb5_authenticate() returns success. Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/linux-cifs/20260702155449.3639773-1-james_montgomery@disroot.org/ Signed-off-by: James Montgomery <james_montgomery@disroot.org> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysproc: Fix broken error paths for namespace linksJann Horn1-1/+3
commit 425224c2d700391729be7fe6929a88ef4e2d7a4e upstream. Don't return the return value of down_read_killable() (0) when a ptrace access check fails, return -EACCES as intended. Reported-by: Magnus Lindholm <linmag7@gmail.com> Closes: https://lore.kernel.org/r/20260706170735.2941493-1-linmag7@gmail.com Fixes: 6650527444da ("proc: protect ptrace_may_access() with exec_update_lock (part 1)") Cc: stable@vger.kernel.org Signed-off-by: Jann Horn <jannh@google.com> Link: https://patch.msgid.link/20260706-procfs-ns-eacces-fix-v1-1-a69ab14c02e6@google.com Tested-by: Magnus Lindholm <linmag7@gmail.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysiomap: fix out-of-bounds bitmap_set() with zero-length rangeZhang Yi1-8/+14
commit 9c7d8f7c8994c790fca501dc45ce66e7356cbe05 upstream. ifs_set_range_dirty() and ifs_set_range_uptodate() compute last_blk as (off + len - 1) >> i_blkbits. When off is 0 and len is 0, the unsigned subtraction underflows to SIZE_MAX, producing a huge last_blk and nr_blks value that causes bitmap_set() to write far beyond the ifs->state allocation. Regarding ifs_set_range_uptodate(), it is temporarily safe because len cannot be passed in as 0. However, for ifs_set_range_dirty() this is reachable from __iomap_write_end(): when copy_folio_from_iter_atomic() returns 0 (e.g. user buffer fault) and the folio is already uptodate, the guard at the top of __iomap_write_end() does not trigger because !folio_test_uptodate() is false, and iomap_set_range_dirty() is called with copied == 0. Add a !len guard to both functions before the computation, so that a zero-length range is a no-op. Fixes: 4ce02c679722 ("iomap: Add per-block dirty state tracking to improve performance") Cc: stable@vger.kernel.org # v6.6 Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Link: https://patch.msgid.link/20260714082325.325163-5-yi.zhang@huaweicloud.com Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysfscrypt: Add missing superblock check in find_or_insert_direct_key()Eric Biggers1-1/+7
commit b5fa40226e71c17847b9ff2816c6ca4133d0d994 upstream. The legacy 'fscrypt_direct_keys' table caches master keys that are used by v1 encryption policies that have FSCRYPT_POLICY_FLAG_DIRECT_KEY. It's just a global table for all filesystems (since the keys can be provided by the legacy process-subscribed keyrings mechanism, which makes it difficult to reuse super_block::s_master_keys). The entries in it ('struct fscrypt_direct_key') do contain a super_block pointer, though, for passing to fscrypt_destroy_inline_crypt_key() when the last inode that references the key is evicted. However, when finding the fscrypt_direct_key for an inode, we weren't actually comparing the super_block pointer. As a result, inodes with different super_blocks could point to the same fscrypt_direct_key. That could extend the lifetime of a fscrypt_direct_key beyond the super_block it points to, causing a use-after-free later. Fix this by creating distinct fscrypt_direct_key structs for distinct super_block structs. Note that this problem doesn't exist in the v2 policy equivalent ("per-mode keys"), since the data structures there are per super_block. Fixes: 22e9947a4b2b ("fscrypt: stop holding extra request_queue references") Cc: stable@vger.kernel.org Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20260717044303.425265-1-ebiggers%40kernel.org Reviewed-by: Christoph Hellwig <hch@lst.de> Link: https://patch.msgid.link/20260719033120.122120-1-ebiggers@kernel.org Signed-off-by: Eric Biggers <ebiggers@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysfs: preserve ACL_DONT_CACHE state in forget_cached_acl()Amir Goldstein1-0/+7
commit 4b9a5458d02e214ef2b384124ca626e3e381d778 upstream. The ACL_DONT_CACHE state is meant to be a constant state for the inode for filesystems that want to opt out of posix acl caching. Commit facd61053cff1 ("fuse: fixes after adapting to new posix acl api") used this facility to opt out of posix acl caching for fuse inodes with fuse server that does not negotiate FUSE_POSIX_ACL (fc->posix_acl). The commit also takes care to gate the forget_all_cached_acls() call in fuse_set_acl() on fc->posix_acl because there is no need for it, but there are other placed in fuse code which call forget_all_cached_acls() unconditional to fc->posix_acl and those cause the loss of the ACL_DONT_CACHE state. This is not only a functional bug. Properly timed, a get_acl() from this fuse filesystem can return a stale cached value, as was observed in tests, because set_acl() does not invalidate the unintentional acl cache. We could fix this in fuse, but it actually makes no sense for the vfs helper forget_cached_acl() to invalidate the ACL_DONT_CACHE state, so let it not do that to fix fuse and future users of ACL_DONT_CACHE. Fixes: facd61053cff1 ("fuse: fixes after adapting to new posix acl api") Cc: stable@vger.kernel.org Signed-off-by: Amir Goldstein <amir73il@gmail.com> Link: https://patch.msgid.link/20260713220932.413004-2-amir73il@gmail.com Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysbinfmt_elf_fdpic: only honour the first PT_INTERPChristian Brauner1-0/+4
commit 3349ef6a366a61d631f6a263d12cea240957719d upstream. The program header scan handles PT_INTERP from a switch nested in the scan loop, so its break leaves the switch and not the loop. A binary carrying more than one PT_INTERP runs the case again and overwrites both interpreter_name and interpreter. The previous name allocation leaks and so does the previous interpreter reference, along with the write denial open_exec() took on it. The denial is never released, so the file stays unwritable for as long as the system runs. An unprivileged caller reaches this with a crafted binary and repeats it at will. binfmt_elf stops at the first PT_INTERP. Do the same here. The flaw dates back to the driver's introduction in the pre-git history tree introduced in v2.6.11 by 91808d6ebe39 ("[PATCH] FRV: Add FDPIC ELF binary format driver"). Link: https://patch.msgid.link/20260721-gezittert-medium-kreide-b41fc1f0277e@brauner Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reviewed-by: Jori Koolstra <jkoolstra@xs4all.nl> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysceph: fix refcount leak in ceph_readdir()WenTao Liang1-1/+6
commit c3e64079d8b9663e3998d0caac9aba915b6b93ae upstream. The ceph_readdir() function allocates a ceph_mds_request via ceph_mdsc_create_request() and stores it in dfi->last_readdir. In the directory entry processing loop, if the entry's offset is less than ctx->pos or if the inode pointer is unexpectedly NULL, the function returns -EIO without releasing the reference held by dfi->last_readdir, causing a refcount leak. Fix this by adding ceph_mdsc_put_request(dfi->last_readdir) before returning on these error paths. Also set dfi->last_readdir to NULL for safety, matching the cleanup done at the normal exit. Cc: stable@vger.kernel.org Fixes: af9ffa6df7e3 ("ceph: add support to readdir for encrypted names") Signed-off-by: WenTao Liang <vulab@iscas.ac.cn> Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysceph: fix pre-auth out-of-bounds read on snaptrace in ceph_handle_caps()Bryam Vargas1-0/+1
commit 4dbc71bcaf9a30abf3920a4e2cc4ed33bba78c02 upstream. ceph_handle_caps() reads snap_trace_len from the wire-format ceph_mds_caps header and uses it unconditionally to build a fake end pointer (snaptrace + snaptrace_len) that is later handed to ceph_update_snap_trace() in the CEPH_CAP_OP_IMPORT case: snaptrace = h + 1; snaptrace_len = le32_to_cpu(h->snap_trace_len); p = snaptrace + snaptrace_len; ... case CEPH_CAP_OP_IMPORT: if (snaptrace_len) { ... if (ceph_update_snap_trace(mdsc, snaptrace, snaptrace + snaptrace_len, false, &realm)) { ... } ceph_update_snap_trace() then decodes a struct ceph_mds_snap_realm from snaptrace using ceph_decode_need(&p, e, sizeof(*ri), bad) with the attacker-supplied fake end e == snaptrace + snaptrace_len. With snaptrace_len == 0xFFFFFFFF the bound check is trivially satisfied, ri = p reads sizeof(struct ceph_mds_snap_realm) past the legitimate msg->front buffer, and ri->num_snaps / ri->num_prior_parent_snaps then drive further out-of-bounds reads of the encoded snap arrays. The eleven msg_version >= 2 .. msg_version >= 12 decoder blocks above the op switch each catch this OOB through their ceph_decode_*_safe() / ceph_decode_need() helpers, but they sit behind a hdr.version-gated if, so a malicious or compromised MDS that sets msg->hdr.version = 1 reaches the IMPORT path with no version-gated decoder having validated snap_trace_len. The shape has been present since ceph_handle_caps() was introduced. Validate snap_trace_len against the message front buffer before consuming it, using the canonical ceph_decode_need() / ceph_has_room() helper. The helper bounds the length with subtraction (n <= end - p, guarded by end >= p) rather than pointer addition, so it is wrap-safe for the attacker-controlled u32 length on 32-bit builds where p + snap_trace_len could overflow the address space. This matches the rest of the ceph decode path (e.g. the pool_ns_len check a few lines below), and the existing goto bad cleanup already covers this exit path. Cc: stable@vger.kernel.org Fixes: a8599bd821d0 ("ceph: capability management") Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me> Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysbinfmt_misc: set have_execfd only once the interpreter is openedChristian Brauner1-3/+2
commit bbf5f639918dc011aaf60aab8480218758ee68c5 upstream. load_misc_binary() raises bprm->have_execfd as soon as it sees the 'O' (or 'C') flag. This happens well before it opens the interpreter. If that open fails the flag stays set on the bprm. binfmt_misc is at the head of the format list so an interpreter open failure that returns -ENOEXEC lets the search fall through to a later format. This means it runs the matched binary directly having never staged an interpreter. So bprm->executable is NULL while have_execfd falsely claims a descriptor is present. Consequently, begin_new_exec() dereferences the missing executable: would_dump(bprm, bprm->executable); and NULL derefs. Had it not, the hand-off later in the same function would have failed anyway. FD_ADD(0, bprm->executable) rejects a NULL file with -ENOMEM. Both sites are past the point of no return so the exec cannot be unwound either way. This can be reached by unprivileged users as binfmt_misc can be mounted in user namespaces. So a user can register an 'O' entry whose interpreter lives on a FUSE mount, have the FUSE server fail the open with -ENOEXEC and execute a native ELF file that matches the entry. have_execfd only means anything alongside the executable it describes which is not set until the interpreter has been opened and staged. So lets raise it there, next to execfd_creds, which is already set at that point. An open failure now leaves it clear, so the fallback format derives credentials from the binary and emits no AT_EXECFD, as it would for any native exec. The argv rewrite load_misc_binary() performs before the open is still not undone. This means the binary sees the interpreter path in argv[0] and its own path in argv[1] but that predates this change and only became observable once the exec stopped faulting. Link: https://patch.msgid.link/20260720-beglichen-kognitiv-organismus-5e1e55326c56@brauner Fixes: bc2bf338d54b ("exec: Remove recursion from search_binary_handler") Cc: stable@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysexec: fix unsigned loop counter wrap in transfer_args_to_stack()Christian Brauner1-1/+1
commit 16cc4f5c1c4b9e45eca7f7deefa5410a292db599 upstream. The stop value is derived from bprm->p >> PAGE_SHIFT. The index variable is an unsigned long. If bprm->p drops below PAGE_SIZE and stop becomes zero the loop condition index >= stop is always true. After the index == 0 iteration the decrement wraps to ULONG_MAX and bprm->page[ULONG_MAX] reads sizeof(void *) bytes in front of the array. The pointer has wrapped to -1. That garbage pointer is then passed to kmap_local_page() and PAGE_SIZE bytes are copied from wherever that lands into the stack of the process being created. And the loop doesn't terminate either... Getting there only requires bprm->p < PAGE_SIZE. On !MMU bprm_set_stack_limit() and bprm_hit_stack_limit() are empty. So the only constraint on how far bprm->p is pushed down is valid_arg_len(), i.e. that each individual string still fits in what is left. bprm->p starts at PAGE_SIZE * MAX_ARG_PAGES - sizeof(void *) so a single argument or environment string of a little over 31 pages leaves it in the first page: Oops - load access fault [#1] CPU: 0 UID: 0 PID: 1 Comm: victim Not tainted 7.2.0-rc4 #1 epc : __memcpy+0xd4/0xf8 ra : transfer_args_to_stack+0xaa/0xae s4 : ffffffffffffffff s2 : 0000000000000000 a1 : ffffffdc98000000 a2 : 0000000000001000 status: 0000000a00001880 badaddr: ffffffdc98000000 cause: 0000000000000005 [<801a5324>] __memcpy+0xd4/0xf8 [<800d5f6a>] load_flat_binary+0x43a/0x65e [<800a2de4>] bprm_execve+0x1d4/0x316 [<800a351a>] do_execveat_common+0x12e/0x138 [<800a3d44>] __riscv_sys_execve+0x38/0x4e Kernel panic - not syncing: Fatal exception in interrupt This is an arcane bug but we should still fix it. Count down from MAX_ARG_PAGES so the loop ends when index reaches stop, stop == 0 included. The iterations performed are unchanged for every other value of stop. Only CONFIG_MMU=n builds are affected, transfer_args_to_stack() is used by binfmt_flat and binfmt_elf_fdpic on nommu only. The loop predates git history. commit 7e7ec6a93434 ("elf_fdpic_transfer_args_to_stack(): make it generic") only moved it from binfmt_elf_fdpic.c into fs/exec.c and narrowed the copy to the used part of the first page. The condition and the decrement are unchanged from 2.6.12-rc2. Link: https://patch.msgid.link/20260721-hochachtung-staumauer-pigmente-15d71f7d7d04@brauner Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reviewed-by: David Hildenbrand (Arm) <david@kernel.org> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysiomap: correct the range of a partial dirty clearZhang Yi1-4/+8
[ Upstream commit 88c26515313169806a412a362b32a1eca53d21bd ] The block range calculation in ifs_clear_range_dirty() is incorrect when partially clearing a range in a folio. We cannot clear the dirty bit of the first block or the last block if the start or end offset is not blocksize-aligned. This has not yet caused any issues since we always clear a whole folio in iomap_writeback_folio(). Fix this by rounding up the first block to blocksize alignment, and calculate the last block by rounding down (using truncation). Correct the nr_blks calculation accordingly. Fixes: 4ce02c679722 ("iomap: Add per-block dirty state tracking to improve performance") Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Link: https://patch.msgid.link/20260714082325.325163-2-yi.zhang@huaweicloud.com Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysovl: fix trusted xattr escape prefix matchingYichong Chen1-1/+1
[ Upstream commit a8e72879cd0d8422c0b47d6d3c1802274fe73b98 ] In the trusted.* xattr namespace, ovl_is_escaped_xattr() compares one byte less than the escaped overlay xattr prefix length. This makes it match "trusted.overlay.overlay" without requiring the trailing dot. As a result, an xattr such as "trusted.overlay.overlayfoo" is incorrectly treated as an escaped overlay xattr. This can be reproduced by setting "trusted.overlay.overlayfoo" on a lower file and listing xattrs through an overlay mount. listxattr() then exposes it as "trusted.overlay.oo", and a following getxattr() on that listed name fails with ENODATA. Compare the full escaped prefix, including the trailing dot, so similarly-prefixed private xattrs are not misclassified. Fixes: dad02fad84cbc ("ovl: Support escaped overlay.* xattrs") Signed-off-by: Yichong Chen <chenyichong@uniontech.com> Link: https://patch.msgid.link/20260708082221.633602-1-chenyichong@uniontech.com Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 dayssmb: client: validate DFS referral PathConsumedYichong Chen1-9/+25
[ Upstream commit f6f5ee2aa33b350c671721b965251c42cebb962e ] parse_dfs_referrals() validates that the response contains the fixed referral entry array and, on for-next, the per-referral string offsets. However, the response also contains a PathConsumed value that is later used for DFS path parsing. If a malformed response provides a PathConsumed value larger than the search name, later DFS parsing can advance beyond the end of the path. Validate PathConsumed against the search name length before storing it in the parsed referral. Fixes: 4ecce920e13a ("CIFS: move DFS response parsing out of SMB1 code") Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Signed-off-by: Yichong Chen <chenyichong@uniontech.com> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysbtrfs: free mapping node on duplicate reloc root insertGuanghui Yang1-0/+1
[ Upstream commit 6a8269b6459ed870a8156c106a0f597383907872 ] __add_reloc_root() allocates a mapping_node before inserting it into rc->reloc_root_tree. If rb_simple_insert() finds an existing entry, it returns the existing rb_node and leaves the newly allocated node unlinked. The error path then returns -EEXIST without freeing the new node. Since the node was never inserted into reloc_root_tree, the later cleanup in put_reloc_control() cannot find it either. Free the newly allocated node before returning -EEXIST. The callers currently assert that -EEXIST should not happen, so this is a defensive cleanup for an unexpected duplicate insert path. If the path is ever reached, the local allocation should still be released. Fixes: 57a304cfd43b ("btrfs: do not panic in __add_reloc_root") Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Guanghui Yang <3497809730@qq.com> Signed-off-by: David Sterba <dsterba@suse.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysbtrfs: don't propagate EXTENT_FLAG_LOGGING to split extent mapsLeo Martins1-2/+2
[ Upstream commit 5eff4d5b17fa1950e80bfd1ba43dc0699e61a644 ] When btrfs_drop_extent_map_range() splits an extent map, the new split maps inherit the original map's flags through a local 'flags' variable. Commit f86f7a75e2fb ("btrfs: use the flags of an extent map to identify the compression type") changed the EXTENT_FLAG_LOGGING clearing to operate on em->flags instead of that local 'flags' copy, so a split of an extent map that is currently being logged wrongly inherits EXTENT_FLAG_LOGGING. The flag is then never cleared on the split, and when it is freed while still on the inode's modified_extents list (for example by the extent map shrinker) it trips the WARN_ON(!list_empty(&em->list)) in btrfs_free_extent_map() and leads to a use-after-free. Clear EXTENT_FLAG_LOGGING from the local 'flags' copy used for the splits and only clear EXTENT_FLAG_PINNED from em->flags, restoring the behaviour prior to f86f7a75e2fb. CC: Jeff Layton <jlayton@kernel.org> Link: https://lore.kernel.org/all/20260629-btrfs-skip-logging-v1-1-4e3a28c1acaf@kernel.org/ Fixes: f86f7a75e2fb ("btrfs: use the flags of an extent map to identify the compression type") Reviewed-by: Jeff Layton <jlayton@kernel.org> Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Leo Martins <loemra.dev@gmail.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysksmbd: validate compound request size before reading StructureSize2Xiang Mei (Microsoft)1-0/+5
[ Upstream commit 15b38176fd1530372905c602fde51fe89ec8c877 ] When ksmbd validates a compound (chained) SMB2 request, ksmbd_smb2_check_message() reads pdu->StructureSize2 without first checking that the compound element is large enough to contain it. StructureSize2 is a 2-byte field at offset 64 (__SMB2_HEADER_STRUCTURE_SIZE) from the start of each element. The compound-walking logic only guarantees that a full 64-byte SMB2 header is present for the trailing element: when NextCommand is 0, len is reduced to the number of bytes remaining after next_smb2_rcv_hdr_off. A remote client can craft a compound request whose last element has exactly 64 bytes, so the 2-byte StructureSize2 read at offset 64 extends one byte past the receive buffer, producing a slab-out-of-bounds read. BUG: KASAN: slab-out-of-bounds in ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402) Read of size 2 at addr ffff888012ae31ac by task kworker/0:1/14 The buggy address is located 172 bytes inside of allocated 173-byte region Workqueue: ksmbd-io handle_ksmbd_work Call Trace: ... kasan_report (mm/kasan/report.c:595) ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402) handle_ksmbd_work (fs/smb/server/server.c:119) process_one_work (kernel/workqueue.c:3314) worker_thread (kernel/workqueue.c:3397) kthread (kernel/kthread.c:436) ret_from_fork (arch/x86/kernel/process.c:158) ret_from_fork_asm (arch/x86/entry/entry_64.S:245) Reject any compound element that is too small to hold StructureSize2 before dereferencing it. Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Reported-by: AutonomousCodeSecurity@microsoft.com Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysksmbd: pin conn during async oplock break notificationQihang1-2/+4
[ Upstream commit aa5d8f3f96aa11a4a54ce993c11ce8af11c546f9 ] smb2_oplock_break_noti() and smb2_lease_break_noti() store a ksmbd_conn pointer in an async ksmbd_work and then queue that work on ksmbd-io. The work only increments conn->r_count, which prevents teardown from passing the pending-request wait after the increment, but it does not pin the struct ksmbd_conn object. If connection teardown races with an oplock break notification, the last conn reference can be dropped before the queued worker finishes. The worker then uses the freed conn in ksmbd_conn_write() and ksmbd_conn_r_count_dec(). Take a real conn reference when publishing the conn pointer to the async work item, and drop it after the notification work has decremented r_count. Apply the same lifetime rule to lease break notification, which uses the same work->conn pattern. Fixes: 3aa660c05924 ("ksmbd: prevent connection release during oplock break notification") Signed-off-by: Qihang <q.h.hack.winter@gmail.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 dayssmb: move some duplicate definitions to common/cifsglob.hZhangGuoDong3-31/+32
[ Upstream commit d877470b59910b5c50383d634dda3782386bba51 ] In order to maintain the code more easily, move duplicate definitions to new common header file. Co-developed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: ZhangGuoDong <zhangguodong@kylinos.cn> Signed-off-by: Steve French <stfrench@microsoft.com> Stable-dep-of: aa5d8f3f96aa ("ksmbd: pin conn during async oplock break notification") Signed-off-by: Sasha Levin <sashal@kernel.org>
13 dayssmb/client: handle overlapping allocated ranges in fallocateHuiwen He1-7/+18
[ Upstream commit b09ae45d85dc816987a71db9eebc54b0ae288e94 ] smb3_simple_fallocate_range() can skip holes when an allocated range returned by the server starts before the current fallocate offset. The skipped hole is not zero-filled, but fallocate still returns success. A later write to that hole may therefore fail with ENOSPC. The function queries allocated ranges so that it can preserve existing contents and write zeroes only into holes. However, the server may return a range that starts before the current fallocate offset. For example, assume the fallocate request is [100, 400) and the only allocated range returned by the server is [0, 200): Request: [100, 400) Server range: [ 0, 200) allocated Correct: [100, 200) allocated data, skip [200, 400) hole, zero-fill Current: [100, 300) skipped [300, 400) zero-filled afterwards The current code adds the full server range length, 200, to the current offset 100 and moves to 300. As a result, the hole in [200, 300) is skipped without being zero-filled. Fix this by advancing only over the part of the allocated range that overlaps the current fallocate offset. Ignore ranges that end before the current offset and reject ranges whose end offset overflows. This also prevents a malformed range length from causing an out-of-bounds zero-buffer read. Fixes: 966a3cb7c7db ("cifs: improve fallocate emulation") Signed-off-by: Huiwen He <hehuiwen@kylinos.cn> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysbtrfs: fix root leak if its reloc root is unexpected in merge_reloc_roots()Filipe Manana1-0/+1
[ Upstream commit ce6050bafb4e33377dc17fcc357736bfc351180c ] If we have an unexpected reloc_root for our root, we jump to the out label but never drop the reference we obtained for root, resulting in a leak. Add a missing btrfs_put_root() call. Fixes: 24213fa46c70 ("btrfs: do proper error handling in merge_reloc_roots") Reviewed-by: Qu Wenruo <wqu@suse.com> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysbtrfs: reject free space cache with more entries than pagesXiang Mei1-0/+3
[ Upstream commit a2d8d5647ed854e38f941741aea45b9eb15a6350 ] When loading a v1 free space cache, __load_free_space_cache() takes num_entries and num_bitmaps straight from the on-disk btrfs_free_space_header. That header is stored in the tree_root under a key with type 0, which the tree-checker has no case for, so neither count is validated before the load trusts it. The load loops num_entries times and maps the next page whenever the current one runs out, going through io_ctl_check_crc() -> io_ctl_map_page(), which does io_ctl->pages[io_ctl->index++]. But pages[] is allocated in io_ctl_init() from the cache inode's i_size, not from num_entries: num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE); io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS); So if num_entries claims more records than the pages can hold, io_ctl->index runs off the end of pages[]. The write side never hits this because io_ctl_add_entry() and io_ctl_add_bitmap() both stop once io_ctl->index >= io_ctl->num_pages; the read side just never had the same check. To trigger it, take a clean cache (num_entries = <N> here), set num_entries in the header to 0x10000, and fix up the leaf checksum so it still passes the tree-checker. The cache inode has i_size = 65536, so num_pages is 16 and pages[] is a 16-pointer (kmalloc-128) array. The load now tries to read 65536 entries, io_ctl->index walks up to 16, and pages[16] is read past the array: BUG: KASAN: slab-out-of-bounds in io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565) Read of size 8 at addr ffff88800c833a80 by task kworker/u8:3/58 io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565) __load_free_space_cache (fs/btrfs/free-space-cache.c:655 fs/btrfs/free-space-cache.c:820) load_free_space_cache (fs/btrfs/free-space-cache.c:1017) caching_thread (fs/btrfs/block-group.c:880) btrfs_work_helper (fs/btrfs/async-thread.c:312) process_one_work worker_thread kthread ret_from_fork free-space-cache.c:420 is io_ctl_map_page(), inlined into io_ctl_check_crc() at line 565, which is why that is the frame KASAN names. The out-of-bounds slot is then treated as a struct page and handed to crc32c(), so the bad read turns into a GP fault. Add the missing check to io_ctl_check_crc(), which is where both the entry loop and the bitmap loop end up. When num_entries is too large the load now fails like any corrupt cache: __load_free_space_cache() drops it and rebuilds the free space from the extent tree, so a valid cache is never rejected. Reported-by: Weiming Shi <bestswngs@gmail.com> Fixes: 5b0e95bf607d ("Btrfs: inline checksums into the disk free space cache") Link: https://lore.kernel.org/linux-btrfs/CAPpSM+RMPByMCKXvM5QFKToxsyNccfuFLWMdD0mfd0wh2Ja62w@mail.gmail.com/ Assisted-by: Claude:claude-opus-4-8 Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Xiang Mei <xmei5@asu.edu> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysfs/proc/task_mmu: fix make_uffd_wp_huge_pte() prot-update raceKiryl Shutsemau1-5/+9
commit 04718f7c9290f95385f0dd328758753dc1c36dec upstream. Patch series "userfaultfd/pagemap: pre-existing fixes". These are pre-existing bug fixes that were carried at the front of the userfaultfd RWP working-set-tracking series up to v5 [1]. Per review feedback that fixes should not sit in the middle of a feature series, they are split out and sent on their own; the RWP series is reposted rebased on top of this. All six were flagged by the Sashiko AI review of the RWP series and carry Reported-by: Sashiko AI review <sashiko-bot@kernel.org>. They are independent of RWP, apply to mm-new directly, and carry Cc: stable@. 1: fs/proc/task_mmu: a missing huge_ptep_modify_prot_start() in make_uffd_wp_huge_pte() can lose hardware Dirty/Accessed updates when PAGEMAP_SCAN write-protects a hugetlb PTE. 2: fs/proc/task_mmu: pagemap_scan_hugetlb_entry() compares the range against HPAGE_SIZE rather than the hstate page size, so it never write-protects gigantic hugetlb pages. 3: fs/proc/task_mmu: PAGEMAP_SCAN with PM_SCAN_WP_MATCHING over an unpopulated hugetlb range self-deadlocks -- pagemap_scan_pte_hole() calls uffd_wp_range() while walk_hugetlb_range() holds the hugetlb vma lock for read, and hugetlb_change_protection() then takes it for write. Install the marker inline instead. 4: mm/huge_memory: change_non_present_huge_pmd() drops pmd_swp_uffd_wp on a device-private PMD permission downgrade, silently losing the uffd-wp marker. 5: userfaultfd: must_wait() applies pte_write() to a locklessly read PTE without checking pte_present(), so swap/migration entries decode random offset bits and a thread can stay parked on a stale fault. 6: userfaultfd: __VMA_UFFD_FLAGS feeds VMA_UFFD_MINOR_BIT (41) to mk_vma_flags() unconditionally, an out-of-bounds write into the single-word vma_flags_t on 32-bit. Build the mask from config-gated per-mode masks so an unavailable bit is never materialised. This patch (of 6): make_uffd_wp_huge_pte() arms the UFFD_WP bit on a present HugeTLB PTE by calling huge_ptep_modify_prot_commit() with a ptent snapshot that was fetched without the corresponding huge_ptep_modify_prot_start(). The start helper is what atomically clears the entry so the kernel-owned snapshot stays consistent until the commit; without it, the hardware may set Dirty or Accessed in the live PTE between the original read and the commit, and huge_ptep_modify_prot_commit() (whose generic implementation just calls set_huge_pte_at()) then writes the stale snapshot back over the live hardware bits, losing the update. The non-hugetlb sibling make_uffd_wp_pte() does this correctly via ptep_modify_prot_start() / ptep_modify_prot_commit(). Mirror that pattern for the present-PTE branch. The migration case stays as-is -- migration entries are non-present, so there's no hardware update to race against. Link: https://lore.kernel.org/20260529172331.356655-1-kas@kernel.org Link: https://lore.kernel.org/20260529172331.356655-2-kas@kernel.org Link: https://lore.kernel.org/all/20260526130509.2748441-1-kirill@shutemov.name/ [1] Fixes: 52526ca7fdb9 ("fs/proc/task_mmu: implement IOCTL to get and optionally clear info about PTEs") Signed-off-by: Kiryl Shutsemau <kas@kernel.org> Reported-by: Sashiko AI review <sashiko-bot@kernel.org> Reviewed-by: Lorenzo Stoakes <ljs@kernel.org> Reviewed-by: Dev Jain <dev.jain@arm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Peter Xu <peterx@redhat.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: Balbir Singh <balbirs@nvidia.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> [ kas: adapt to the pre-softleaf idiom; apply the huge_ptep_modify_prot_start()/commit() fix to the present-PTE (!huge_pte_none()) branch ] Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-07-29mm: refactor mm_access() to not return NULLLorenzo Stoakes1-12/+14
[ Upstream commit cd3f8467afd470ccab0de2fbc7c76664af4a0bac ] mm_access() can return NULL if the mm is not found, but this is handled the same as an error in all callers, with some translating this into an -ESRCH error. Only proc_mem_open() returns NULL if no mm is found, however in this case it is clearer and makes more sense to explicitly handle the error. Additionally we take the opportunity to refactor the function to eliminate unnecessary nesting. Simplify things by simply returning -ESRCH if no mm is found - this both eliminates confusing use of the IS_ERR_OR_NULL() macro, and simplifies callers which would return -ESRCH by returning this error directly. [lorenzo.stoakes@oracle.com: prefer neater pointer error comparison] Link: https://lkml.kernel.org/r/2fae1834-749a-45e1-8594-5e5979cf7103@lucifer.local Link: https://lkml.kernel.org/r/20240924201023.193135-1-lorenzo.stoakes@oracle.com Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Suggested-by: Arnd Bergmann <arnd@arndb.de> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-07-25ext4: fix fd leak in EXT4_IOC_MOVE_EXT cross-sb validationYun Zhou1-2/+4
The backport of upstream commit c143957520c6 ("ext4: validate donor file superblock early in EXT4_IOC_MOVE_EXT") uses a bare 'return -EXDEV' which is safe upstream because the fd is managed via CLASS(fd) with automatic cleanup (commit 8152f8201088 ("fdget(), more trivial conversions")). However, on 6.12.y the ioctl still uses the traditional fdget/fdput pattern, so the bare return bypasses fdput(donor) at the mext_out label, leaking the file reference. Fix by setting err and using goto mext_out. Fixes: 74796e886ca3 ("ext4: validate donor file superblock early in EXT4_IOC_MOVE_EXT") Reported-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com> Signed-off-by: Yun Zhou <yun.zhou@windriver.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-07-24afs: Fix afs_dynroot_readdir() to not use the RCU read lockDavid Howells1-2/+2
commit a64e4d48a0b77e4ada19ac26ca3a08cd492f6362 upstream. afs_dynroot_readdir() uses the RCU read lock to walk the cell list whilst emitting cell automount entries - but dir_emit() may write to a userspace buffer, thereby causing a fault to occur and waits to happen. Fix afs_dynroot_readdir() to get a shared lock on net->cells_lock instead. This can be triggered by enabling lockdep, preconfiguring a number of cells, doing "mount -t afs none /afs -o dyn" (or using the kafs-client package with afs.mount systemd unit enabled) and then doing "ls /afs". Fixes: 1d0b929fc070 ("afs: Change dynroot to create contents on demand") Reported-by: syzbot+3b6c5c6a1d0119b687a1@syzkaller.appspotmail.com Reported-by: syzbot+8245611446194a52150d@syzkaller.appspotmail.com Reported-by: syzbot+1aa62e6852a6ad1c7944@syzkaller.appspotmail.com Reported-by: syzbot+54e6c2176ba76c56217e@syzkaller.appspotmail.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://lore.kernel.org/1638014.1744145189@warthog.procyon.org.uk cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-07-24afs: Fix afs_atcell_get_link() to check if ws_cell is unset firstDavid Howells1-3/+3
commit 0307d16f3610eb29ad0b7529846de7d62fed60ca upstream. Fix afs_atcell_get_link() to check if the workstation cell is unset before doing the RCU pathwalk bit where we dereference that. Fixes: 823869e1e616 ("afs: Fix afs_atcell_get_link() to handle RCU pathwalk") Reported-by: syzbot+76a6f18e3af82e84f264@syzkaller.appspotmail.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://lore.kernel.org/r/2481796.1742296819@warthog.procyon.org.uk Tested-by: syzbot+76a6f18e3af82e84f264@syzkaller.appspotmail.com cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-07-24ksmbd: fix durable reconnect double-bind race in ksmbd_reopen_durable_fdGil Portnoy1-3/+9
commit 7ce4fc40018de07f05f3035241122d992610dbfb upstream. Two concurrent same-user DHnC reconnects can both observe fp->conn == NULL before either sets it. ksmbd_reopen_durable_fd() checks fp->conn to guard against a handle already being reconnected, but the check and the binding assignment are not atomic: both threads pass the guard, both call ksmbd_conn_get() on the same fp, and both eventually reach kfree(fp->owner.name) -- a double-free of the owner.name slab object. The double-bound ksmbd_file also causes a write-UAF on the 344-byte ksmbd_file_cache object when a concurrent smb2_close() spins on fp->f_lock after the object has been freed by the losing reconnect path. KASAN on 7.1-rc5 (48-thread concurrent reconnect, 3000 cycles): BUG: KASAN: double-free in ksmbd_reopen_durable_fd+0x268/0x308 BUG: KASAN: slab-use-after-free in _raw_spin_lock+0xac/0x150 Write of size 4 at offset 24 into freed ksmbd_file_cache object Five double-bind windows observed; 63 total KASAN reports triggered. Fix: validate and claim fp->conn under write_lock(&global_ft.lock) so the check-and-claim is atomic. ksmbd_lookup_durable_fd() already treats fp->conn != NULL as "in use" and skips such an fp; setting fp->conn before dropping the lock closes the race. ksmbd_conn_get() is a non-sleeping refcount increment, safe under the rwlock. The rollback path on __open_id() failure also clears fp->conn/tcon under the lock so concurrent readers see a consistent state. Fixes: b1f1e80620de ("ksmbd: centralize ksmbd_conn final release to plug transport leak") Assisted-by: Henry (Claude):claude-opus-4 Signed-off-by: Gil Portnoy <dddhkts1@gmail.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>