FAILED: patch "[PATCH] filelock: Remove locks reliably when fcntl/close race is" failed to apply to 5.4-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.4.y
git checkout FETCH_HEAD
git cherry-pick -x 3cad1bc010416c6dd780643476bc59ed742436b9
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2024070802-nebula-stir-11eb@gregkh' --subject-prefix 'PATCH 5.4.y' HEAD^..
Possible dependencies:
3cad1bc01041 ("filelock: Remove locks reliably when fcntl/close race is detected") 4ca52f539865 ("filelock: have fs/locks.c deal with file_lock_core directly")a69ce85ec9af ("filelock: split common fields into struct file_lock_core")3d40f78169a0 ("filelock: drop the IS_* macros")75cabec0111b ("filelock: add some new helper functions")587a67b6830b ("filelock: rename some fields in tracepoints")0e9876d8e88d ("filelock: fl_pid field should be signed int")6c9007f65d14 ("fs/locks: F_UNLCK extension for F_OFD_GETLK")dc592190a554 ("fs/locks: Remove redundant assignment to cmd")3822a7c40997 ("Merge tag 'mm-stable-2023-02-20-13-37' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 3cad1bc010416c6dd780643476bc59ed742436b9 Mon Sep 17 00:00:00 2001
From: Jann Horn <[email protected]>
Date: Tue, 2 Jul 2024 18:26:52 +0200
Subject: [PATCH] filelock: Remove locks reliably when fcntl/close race is
detected
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().
fs/locks.c +4 -5
@@ -2448,8 +2448,9 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, 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->c.flc_type != F_UNLCK &&
@@ -2464,9 +2465,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, f =files_lookup_fd_locked (files, fd);spin_unlock (&files->file_lock);if (f != filp) { - file_lock->c.flc_type =F_UNLCK ; - error =do_lock_file_wait (filp, cmd, file_lock); -WARN_ON_ONCE (error); +locks_remove_posix (filp, files); error = -EBADF ; } }