From: Greg Kroah-Hartman Date: Mon, 7 Nov 2016 16:23:48 +0000 (+0100) Subject: 4.4-stable patches X-Git-Tag: v4.4.31~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=83b32dbed380d13794237255ac2048af034663d1;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches 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 --- 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 index 00000000000..600464699aa --- /dev/null +++ b/queue-4.4/android-binder-add-strong-ref-checks.patch @@ -0,0 +1,107 @@ +From 0a3ffab93fe52530602fe47cd74802cffdb19c05 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= +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 + +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 +Signed-off-by: Martijn Coenen +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d1a0c52f4fe --- /dev/null +++ b/queue-4.4/android-binder-clear-binder-and-cookie-when-setting-handle-in-flat-binder-struct.patch @@ -0,0 +1,52 @@ +From 4afb604e2d14d429ac9e1fd84b952602853b2df5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= +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 + +commit 4afb604e2d14d429ac9e1fd84b952602853b2df5 upstream. + +Prevents leaking pointers between processes + +Signed-off-by: Arve Hjønnevåg +Signed-off-by: Martijn Coenen +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..4e9d4f449a3 --- /dev/null +++ b/queue-4.4/btrfs-fix-races-on-root_log_ctx-lists.patch @@ -0,0 +1,84 @@ +From 570dd45042a7c8a7aba1ee029c5dd0f5ccf41b9b Mon Sep 17 00:00:00 2001 +From: Chris Mason +Date: Thu, 27 Oct 2016 10:42:20 -0700 +Subject: btrfs: fix races on root_log_ctx lists + +From: Chris Mason + +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 +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-4.4/series b/queue-4.4/series index e91d90c677a..1870c6d7867 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -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