]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 4 Mar 2016 01:30:26 +0000 (17:30 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 4 Mar 2016 01:30:26 +0000 (17:30 -0800)
added patches:
locks-fix-unlock-when-fcntl_setlk-races-with-a-close.patch

queue-3.10/locks-fix-unlock-when-fcntl_setlk-races-with-a-close.patch [new file with mode: 0644]
queue-3.10/series [new file with mode: 0644]
queue-3.14/series [new file with mode: 0644]
queue-4.4/series [new file with mode: 0644]

diff --git a/queue-3.10/locks-fix-unlock-when-fcntl_setlk-races-with-a-close.patch b/queue-3.10/locks-fix-unlock-when-fcntl_setlk-races-with-a-close.patch
new file mode 100644 (file)
index 0000000..e7f1fd7
--- /dev/null
@@ -0,0 +1,121 @@
+From 7f3697e24dc3820b10f445a4a7d914fc356012d1 Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jeff.layton@primarydata.com>
+Date: Thu, 7 Jan 2016 16:38:10 -0500
+Subject: locks: fix unlock when fcntl_setlk races with a close
+
+From: Jeff Layton <jeff.layton@primarydata.com>
+
+commit 7f3697e24dc3820b10f445a4a7d914fc356012d1 upstream.
+
+Dmitry reported that he was able to reproduce the WARN_ON_ONCE that
+fires in locks_free_lock_context when the flc_posix list isn't empty.
+
+The problem turns out to be that we're basically rebuilding the
+file_lock from scratch in fcntl_setlk when we discover that the setlk
+has raced with a close. If the l_whence field is SEEK_CUR or SEEK_END,
+then we may end up with fl_start and fl_end values that differ from
+when the lock was initially set, if the file position or length of the
+file has changed in the interim.
+
+Fix this by just reusing the same lock request structure, and simply
+override fl_type value with F_UNLCK as appropriate. That ensures that
+we really are unlocking the lock that was initially set.
+
+While we're there, make sure that we do pop a WARN_ON_ONCE if the
+removal ever fails. Also return -EBADF in this event, since that's
+what we would have returned if the close had happened earlier.
+
+Cc: Alexander Viro <viro@zeniv.linux.org.uk>
+Fixes: c293621bbf67 (stale POSIX lock handling)
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
+Acked-by: "J. Bruce Fields" <bfields@fieldses.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/locks.c |   51 ++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 30 insertions(+), 21 deletions(-)
+
+--- a/fs/locks.c
++++ b/fs/locks.c
+@@ -1852,7 +1852,6 @@ int fcntl_setlk(unsigned int fd, struct
+               goto out;
+       }
+-again:
+       error = flock_to_posix_lock(filp, file_lock, &flock);
+       if (error)
+               goto out;
+@@ -1883,19 +1882,22 @@ again:
+        * Attempt to detect a close/fcntl race and recover by
+        * releasing the lock that was just acquired.
+        */
+-      /*
+-       * we need that spin_lock here - it prevents reordering between
+-       * update of inode->i_flock and check for it done in close().
+-       * rcu_read_lock() wouldn't do.
+-       */
+-      spin_lock(&current->files->file_lock);
+-      f = fcheck(fd);
+-      spin_unlock(&current->files->file_lock);
+-      if (!error && f != filp && flock.l_type != F_UNLCK) {
+-              flock.l_type = F_UNLCK;
+-              goto again;
++      if (!error && file_lock->fl_type != F_UNLCK) {
++              /*
++               * We need that spin_lock here - it prevents reordering between
++               * update of inode->i_flock and check for it done in
++               * close(). rcu_read_lock() wouldn't do.
++               */
++              spin_lock(&current->files->file_lock);
++              f = fcheck(fd);
++              spin_unlock(&current->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);
++                      error = -EBADF;
++              }
+       }
+-
+ out:
+       locks_free_lock(file_lock);
+       return error;
+@@ -1970,7 +1972,6 @@ int fcntl_setlk64(unsigned int fd, struc
+               goto out;
+       }
+-again:
+       error = flock64_to_posix_lock(filp, file_lock, &flock);
+       if (error)
+               goto out;
+@@ -2001,14 +2002,22 @@ again:
+        * Attempt to detect a close/fcntl race and recover by
+        * releasing the lock that was just acquired.
+        */
+-      spin_lock(&current->files->file_lock);
+-      f = fcheck(fd);
+-      spin_unlock(&current->files->file_lock);
+-      if (!error && f != filp && flock.l_type != F_UNLCK) {
+-              flock.l_type = F_UNLCK;
+-              goto again;
++      if (!error && file_lock->fl_type != F_UNLCK) {
++              /*
++               * We need that spin_lock here - it prevents reordering between
++               * update of inode->i_flock and check for it done in
++               * close(). rcu_read_lock() wouldn't do.
++               */
++              spin_lock(&current->files->file_lock);
++              f = fcheck(fd);
++              spin_unlock(&current->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);
++                      error = -EBADF;
++              }
+       }
+-
+ out:
+       locks_free_lock(file_lock);
+       return error;
diff --git a/queue-3.10/series b/queue-3.10/series
new file mode 100644 (file)
index 0000000..2f9ecde
--- /dev/null
@@ -0,0 +1 @@
+locks-fix-unlock-when-fcntl_setlk-races-with-a-close.patch
diff --git a/queue-3.14/series b/queue-3.14/series
new file mode 100644 (file)
index 0000000..18b7bd9
--- /dev/null
@@ -0,0 +1,2 @@
+bio-return-eintr-if-copying-to-user-space-got-interrupted.patch
+locks-fix-unlock-when-fcntl_setlk-races-with-a-close.patch
diff --git a/queue-4.4/series b/queue-4.4/series
new file mode 100644 (file)
index 0000000..aa442a6
--- /dev/null
@@ -0,0 +1,7 @@
+use-d_seq-to-get-coherency-between-d_inode-and-d_flags.patch
+drivers-sh-restore-legacy-clock-domain-on-superh-platforms.patch
+btrfs-fix-deadlock-running-delayed-iputs-at-transaction-commit-time.patch
+btrfs-fix-no_space-in-write-and-rm-loop.patch
+btrfs-async-thread-fix-a-use-after-free-error-for-trace.patch
+drm-amdgpu-mask-out-wc-from-bo-on-unsupported-arches.patch
+block-initialize-max_dev_sectors-to-0.patch