]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 7 Nov 2016 16:23:48 +0000 (17:23 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 7 Nov 2016 16:23:48 +0000 (17:23 +0100)
added patches:
android-binder-add-strong-ref-checks.patch
android-binder-clear-binder-and-cookie-when-setting-handle-in-flat-binder-struct.patch
btrfs-fix-races-on-root_log_ctx-lists.patch

queue-4.4/android-binder-add-strong-ref-checks.patch [new file with mode: 0644]
queue-4.4/android-binder-clear-binder-and-cookie-when-setting-handle-in-flat-binder-struct.patch [new file with mode: 0644]
queue-4.4/btrfs-fix-races-on-root_log_ctx-lists.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/android-binder-add-strong-ref-checks.patch b/queue-4.4/android-binder-add-strong-ref-checks.patch
new file mode 100644 (file)
index 0000000..6004646
--- /dev/null
@@ -0,0 +1,107 @@
+From 0a3ffab93fe52530602fe47cd74802cffdb19c05 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= <arve@android.com>
+Date: Mon, 24 Oct 2016 15:20:29 +0200
+Subject: ANDROID: binder: Add strong ref checks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arve Hjønnevåg <arve@android.com>
+
+commit 0a3ffab93fe52530602fe47cd74802cffdb19c05 upstream.
+
+Prevent using a binder_ref with only weak references where a strong
+reference is required.
+
+Signed-off-by: Arve Hjønnevåg <arve@android.com>
+Signed-off-by: Martijn Coenen <maco@android.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/android/binder.c |   30 +++++++++++++++++++++---------
+ 1 file changed, 21 insertions(+), 9 deletions(-)
+
+--- a/drivers/android/binder.c
++++ b/drivers/android/binder.c
+@@ -1003,7 +1003,7 @@ static int binder_dec_node(struct binder
+ static struct binder_ref *binder_get_ref(struct binder_proc *proc,
+-                                       uint32_t desc)
++                                       u32 desc, bool need_strong_ref)
+ {
+       struct rb_node *n = proc->refs_by_desc.rb_node;
+       struct binder_ref *ref;
+@@ -1011,12 +1011,16 @@ static struct binder_ref *binder_get_ref
+       while (n) {
+               ref = rb_entry(n, struct binder_ref, rb_node_desc);
+-              if (desc < ref->desc)
++              if (desc < ref->desc) {
+                       n = n->rb_left;
+-              else if (desc > ref->desc)
++              } else if (desc > ref->desc) {
+                       n = n->rb_right;
+-              else
++              } else if (need_strong_ref && !ref->strong) {
++                      binder_user_error("tried to use weak ref as strong ref\n");
++                      return NULL;
++              } else {
+                       return ref;
++              }
+       }
+       return NULL;
+ }
+@@ -1286,7 +1290,10 @@ static void binder_transaction_buffer_re
+               } break;
+               case BINDER_TYPE_HANDLE:
+               case BINDER_TYPE_WEAK_HANDLE: {
+-                      struct binder_ref *ref = binder_get_ref(proc, fp->handle);
++                      struct binder_ref *ref;
++
++                      ref = binder_get_ref(proc, fp->handle,
++                                           fp->type == BINDER_TYPE_HANDLE);
+                       if (ref == NULL) {
+                               pr_err("transaction release %d bad handle %d\n",
+@@ -1380,7 +1387,7 @@ static void binder_transaction(struct bi
+               if (tr->target.handle) {
+                       struct binder_ref *ref;
+-                      ref = binder_get_ref(proc, tr->target.handle);
++                      ref = binder_get_ref(proc, tr->target.handle, true);
+                       if (ref == NULL) {
+                               binder_user_error("%d:%d got transaction to invalid handle\n",
+                                       proc->pid, thread->pid);
+@@ -1583,7 +1590,10 @@ static void binder_transaction(struct bi
+               } break;
+               case BINDER_TYPE_HANDLE:
+               case BINDER_TYPE_WEAK_HANDLE: {
+-                      struct binder_ref *ref = binder_get_ref(proc, fp->handle);
++                      struct binder_ref *ref;
++
++                      ref = binder_get_ref(proc, fp->handle,
++                                           fp->type == BINDER_TYPE_HANDLE);
+                       if (ref == NULL) {
+                               binder_user_error("%d:%d got transaction with invalid handle, %d\n",
+@@ -1794,7 +1804,9 @@ static int binder_thread_write(struct bi
+                                               ref->desc);
+                               }
+                       } else
+-                              ref = binder_get_ref(proc, target);
++                              ref = binder_get_ref(proc, target,
++                                                   cmd == BC_ACQUIRE ||
++                                                   cmd == BC_RELEASE);
+                       if (ref == NULL) {
+                               binder_user_error("%d:%d refcount change on invalid ref %d\n",
+                                       proc->pid, thread->pid, target);
+@@ -1990,7 +2002,7 @@ static int binder_thread_write(struct bi
+                       if (get_user(cookie, (binder_uintptr_t __user *)ptr))
+                               return -EFAULT;
+                       ptr += sizeof(binder_uintptr_t);
+-                      ref = binder_get_ref(proc, target);
++                      ref = binder_get_ref(proc, target, false);
+                       if (ref == NULL) {
+                               binder_user_error("%d:%d %s invalid ref %d\n",
+                                       proc->pid, thread->pid,
diff --git a/queue-4.4/android-binder-clear-binder-and-cookie-when-setting-handle-in-flat-binder-struct.patch b/queue-4.4/android-binder-clear-binder-and-cookie-when-setting-handle-in-flat-binder-struct.patch
new file mode 100644 (file)
index 0000000..d1a0c52
--- /dev/null
@@ -0,0 +1,52 @@
+From 4afb604e2d14d429ac9e1fd84b952602853b2df5 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= <arve@android.com>
+Date: Mon, 24 Oct 2016 15:20:30 +0200
+Subject: ANDROID: binder: Clear binder and cookie when setting handle in flat binder struct
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arve Hjønnevåg <arve@android.com>
+
+commit 4afb604e2d14d429ac9e1fd84b952602853b2df5 upstream.
+
+Prevents leaking pointers between processes
+
+Signed-off-by: Arve Hjønnevåg <arve@android.com>
+Signed-off-by: Martijn Coenen <maco@android.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/android/binder.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/android/binder.c
++++ b/drivers/android/binder.c
+@@ -1578,7 +1578,9 @@ static void binder_transaction(struct bi
+                               fp->type = BINDER_TYPE_HANDLE;
+                       else
+                               fp->type = BINDER_TYPE_WEAK_HANDLE;
++                      fp->binder = 0;
+                       fp->handle = ref->desc;
++                      fp->cookie = 0;
+                       binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE,
+                                      &thread->todo);
+@@ -1628,7 +1630,9 @@ static void binder_transaction(struct bi
+                                       return_error = BR_FAILED_REPLY;
+                                       goto err_binder_get_ref_for_node_failed;
+                               }
++                              fp->binder = 0;
+                               fp->handle = new_ref->desc;
++                              fp->cookie = 0;
+                               binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL);
+                               trace_binder_transaction_ref_to_ref(t, ref,
+                                                                   new_ref);
+@@ -1682,6 +1686,7 @@ static void binder_transaction(struct bi
+                       binder_debug(BINDER_DEBUG_TRANSACTION,
+                                    "        fd %d -> %d\n", fp->handle, target_fd);
+                       /* TODO: fput? */
++                      fp->binder = 0;
+                       fp->handle = target_fd;
+               } break;
diff --git a/queue-4.4/btrfs-fix-races-on-root_log_ctx-lists.patch b/queue-4.4/btrfs-fix-races-on-root_log_ctx-lists.patch
new file mode 100644 (file)
index 0000000..4e9d4f4
--- /dev/null
@@ -0,0 +1,84 @@
+From 570dd45042a7c8a7aba1ee029c5dd0f5ccf41b9b Mon Sep 17 00:00:00 2001
+From: Chris Mason <clm@fb.com>
+Date: Thu, 27 Oct 2016 10:42:20 -0700
+Subject: btrfs: fix races on root_log_ctx lists
+
+From: Chris Mason <clm@fb.com>
+
+commit 570dd45042a7c8a7aba1ee029c5dd0f5ccf41b9b upstream.
+
+btrfs_remove_all_log_ctxs takes a shortcut where it avoids walking the
+list because it knows all of the waiters are patiently waiting for the
+commit to finish.
+
+But, there's a small race where btrfs_sync_log can remove itself from
+the list if it finds a log commit is already done.  Also, it uses
+list_del_init() to remove itself from the list, but there's no way to
+know if btrfs_remove_all_log_ctxs has already run, so we don't know for
+sure if it is safe to call list_del_init().
+
+This gets rid of all the shortcuts for btrfs_remove_all_log_ctxs(), and
+just calls it with the proper locking.
+
+This is part two of the corruption fixed by cbd60aa7cd1.  I should have
+done this in the first place, but convinced myself the optimizations were
+safe.  A 12 hour run of dbench 2048 will eventually trigger a list debug
+WARN_ON for the list_del_init() in btrfs_sync_log().
+
+Fixes: d1433debe7f4346cf9fc0dafc71c3137d2a97bc4
+Reported-by: Dave Jones <davej@codemonkey.org.uk>
+Signed-off-by: Chris Mason <clm@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/tree-log.c |   20 ++++++--------------
+ 1 file changed, 6 insertions(+), 14 deletions(-)
+
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -2696,14 +2696,12 @@ static inline void btrfs_remove_all_log_
+                                            int index, int error)
+ {
+       struct btrfs_log_ctx *ctx;
++      struct btrfs_log_ctx *safe;
+-      if (!error) {
+-              INIT_LIST_HEAD(&root->log_ctxs[index]);
+-              return;
+-      }
+-
+-      list_for_each_entry(ctx, &root->log_ctxs[index], list)
++      list_for_each_entry_safe(ctx, safe, &root->log_ctxs[index], list) {
++              list_del_init(&ctx->list);
+               ctx->log_ret = error;
++      }
+       INIT_LIST_HEAD(&root->log_ctxs[index]);
+ }
+@@ -2944,13 +2942,9 @@ int btrfs_sync_log(struct btrfs_trans_ha
+       mutex_unlock(&root->log_mutex);
+ out_wake_log_root:
+-      /*
+-       * We needn't get log_mutex here because we are sure all
+-       * the other tasks are blocked.
+-       */
++      mutex_lock(&log_root_tree->log_mutex);
+       btrfs_remove_all_log_ctxs(log_root_tree, index2, ret);
+-      mutex_lock(&log_root_tree->log_mutex);
+       log_root_tree->log_transid_committed++;
+       atomic_set(&log_root_tree->log_commit[index2], 0);
+       mutex_unlock(&log_root_tree->log_mutex);
+@@ -2961,10 +2955,8 @@ out_wake_log_root:
+       if (waitqueue_active(&log_root_tree->log_commit_wait[index2]))
+               wake_up(&log_root_tree->log_commit_wait[index2]);
+ out:
+-      /* See above. */
+-      btrfs_remove_all_log_ctxs(root, index1, ret);
+-
+       mutex_lock(&root->log_mutex);
++      btrfs_remove_all_log_ctxs(root, index1, ret);
+       root->log_transid_committed++;
+       atomic_set(&root->log_commit[index1], 0);
+       mutex_unlock(&root->log_mutex);
index e91d90c677a8f5f6365263e3dd4ed996b984a23d..1870c6d7867d8e92916fad8f94a323fd632b5286 100644 (file)
@@ -13,3 +13,6 @@ alsa-hda-raise-azx_dcaps_rirb_delay-handling-into-top-drivers.patch
 alsa-hda-allow-40-bit-dma-mask-for-nvidia-devices.patch
 alsa-hda-adding-a-new-group-of-pin-cfg-into-alc295-pin-quirk-table.patch
 alsa-hda-fix-headset-mic-detection-problem-for-two-dell-laptops.patch
+android-binder-add-strong-ref-checks.patch
+android-binder-clear-binder-and-cookie-when-setting-handle-in-flat-binder-struct.patch
+btrfs-fix-races-on-root_log_ctx-lists.patch