From: Greg Kroah-Hartman Date: Mon, 22 Jul 2024 16:35:53 +0000 (+0200) Subject: 6.6-stable patches X-Git-Tag: v6.10.1~40 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=912e09a3a7f9c5e34d15b35f4b418014b1dda9e0;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: filelock-remove-locks-reliably-when-fcntl-close-race-is-detected.patch --- diff --git a/queue-6.6/filelock-remove-locks-reliably-when-fcntl-close-race-is-detected.patch b/queue-6.6/filelock-remove-locks-reliably-when-fcntl-close-race-is-detected.patch new file mode 100644 index 00000000000..d9196c95c27 --- /dev/null +++ b/queue-6.6/filelock-remove-locks-reliably-when-fcntl-close-race-is-detected.patch @@ -0,0 +1,66 @@ +From 3cad1bc010416c6dd780643476bc59ed742436b9 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Tue, 2 Jul 2024 18:26:52 +0200 +Subject: filelock: Remove locks reliably when fcntl/close race is detected + +From: Jann Horn + +commit 3cad1bc010416c6dd780643476bc59ed742436b9 upstream. + +When fcntl_setlk() races with close(), it removes the created lock with +do_lock_file_wait(). +However, LSMs can allow the first do_lock_file_wait() that created the lock +while denying the second do_lock_file_wait() that tries to remove the lock. +In theory (but AFAIK not in practice), posix_lock_file() could also fail to +remove a lock due to GFP_KERNEL allocation failure (when splitting a range +in the middle). + +After the bug has been triggered, use-after-free reads will occur in +lock_get_status() when userspace reads /proc/locks. This can likely be used +to read arbitrary kernel memory, but can't corrupt kernel memory. +This only affects systems with SELinux / Smack / AppArmor / BPF-LSM in +enforcing mode and only works from some security contexts. + +Fix it by calling locks_remove_posix() instead, which is designed to +reliably get rid of POSIX locks associated with the given file and +files_struct and is also used by filp_flush(). + +Fixes: c293621bbf67 ("[PATCH] stale POSIX lock handling") +Cc: stable@kernel.org +Link: https://bugs.chromium.org/p/project-zero/issues/detail?id=2563 +Signed-off-by: Jann Horn +Link: https://lore.kernel.org/r/20240702-fs-lock-recover-2-v1-1-edd456f63789@google.com +Reviewed-by: Jeff Layton +Signed-off-by: Christian Brauner +[stable fixup: ->c.flc_type was ->fl_type in older kernels] +Signed-off-by: Jann Horn +Signed-off-by: Greg Kroah-Hartman +--- + fs/locks.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/fs/locks.c ++++ b/fs/locks.c +@@ -2381,8 +2381,9 @@ int fcntl_setlk(unsigned int fd, struct + error = do_lock_file_wait(filp, cmd, file_lock); + + /* +- * Attempt to detect a close/fcntl race and recover by releasing the +- * lock that was just acquired. There is no need to do that when we're ++ * Detect close/fcntl races and recover by zapping all POSIX locks ++ * associated with this file and our files_struct, just like on ++ * filp_flush(). There is no need to do that when we're + * unlocking though, or for OFD locks. + */ + if (!error && file_lock->fl_type != F_UNLCK && +@@ -2397,9 +2398,7 @@ int fcntl_setlk(unsigned int fd, struct + f = files_lookup_fd_locked(files, fd); + spin_unlock(&files->file_lock); + if (f != filp) { +- file_lock->fl_type = F_UNLCK; +- error = do_lock_file_wait(filp, cmd, file_lock); +- WARN_ON_ONCE(error); ++ locks_remove_posix(filp, files); + error = -EBADF; + } + } diff --git a/queue-6.6/series b/queue-6.6/series index e69de29bb2d..9d8a95e2700 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -0,0 +1 @@ +filelock-remove-locks-reliably-when-fcntl-close-race-is-detected.patch