aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/android
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/android')
-rw-r--r--drivers/android/binder.c104
-rw-r--r--drivers/android/binder_alloc.c24
-rw-r--r--drivers/android/binder_alloc.h1
3 files changed, 77 insertions, 52 deletions
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index ab34239a76ee..fddf76ef5bd6 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2582,6 +2582,48 @@ static bool binder_proc_transaction(struct binder_transaction *t,
2582 return true; 2582 return true;
2583} 2583}
2584 2584
2585/**
2586 * binder_get_node_refs_for_txn() - Get required refs on node for txn
2587 * @node: struct binder_node for which to get refs
2588 * @proc: returns @node->proc if valid
2589 * @error: if no @proc then returns BR_DEAD_REPLY
2590 *
2591 * User-space normally keeps the node alive when creating a transaction
2592 * since it has a reference to the target. The local strong ref keeps it
2593 * alive if the sending process dies before the target process processes
2594 * the transaction. If the source process is malicious or has a reference
2595 * counting bug, relying on the local strong ref can fail.
2596 *
2597 * Since user-space can cause the local strong ref to go away, we also take
2598 * a tmpref on the node to ensure it survives while we are constructing
2599 * the transaction. We also need a tmpref on the proc while we are
2600 * constructing the transaction, so we take that here as well.
2601 *
2602 * Return: The target_node with refs taken or NULL if no @node->proc is NULL.
2603 * Also sets @proc if valid. If the @node->proc is NULL indicating that the
2604 * target proc has died, @error is set to BR_DEAD_REPLY
2605 */
2606static struct binder_node *binder_get_node_refs_for_txn(
2607 struct binder_node *node,
2608 struct binder_proc **procp,
2609 uint32_t *error)
2610{
2611 struct binder_node *target_node = NULL;
2612
2613 binder_node_inner_lock(node);
2614 if (node->proc) {
2615 target_node = node;
2616 binder_inc_node_nilocked(node, 1, 0, NULL);
2617 binder_inc_node_tmpref_ilocked(node);
2618 node->proc->tmp_ref++;
2619 *procp = node->proc;
2620 } else
2621 *error = BR_DEAD_REPLY;
2622 binder_node_inner_unlock(node);
2623
2624 return target_node;
2625}
2626
2585static void binder_transaction(struct binder_proc *proc, 2627static void binder_transaction(struct binder_proc *proc,
2586 struct binder_thread *thread, 2628 struct binder_thread *thread,
2587 struct binder_transaction_data *tr, int reply, 2629 struct binder_transaction_data *tr, int reply,
@@ -2685,43 +2727,35 @@ static void binder_transaction(struct binder_proc *proc,
2685 ref = binder_get_ref_olocked(proc, tr->target.handle, 2727 ref = binder_get_ref_olocked(proc, tr->target.handle,
2686 true); 2728 true);
2687 if (ref) { 2729 if (ref) {
2688 binder_inc_node(ref->node, 1, 0, NULL); 2730 target_node = binder_get_node_refs_for_txn(
2689 target_node = ref->node; 2731 ref->node, &target_proc,
2690 } 2732 &return_error);
2691 binder_proc_unlock(proc); 2733 } else {
2692 if (target_node == NULL) {
2693 binder_user_error("%d:%d got transaction to invalid handle\n", 2734 binder_user_error("%d:%d got transaction to invalid handle\n",
2694 proc->pid, thread->pid); 2735 proc->pid, thread->pid);
2695 return_error = BR_FAILED_REPLY; 2736 return_error = BR_FAILED_REPLY;
2696 return_error_param = -EINVAL;
2697 return_error_line = __LINE__;
2698 goto err_invalid_target_handle;
2699 } 2737 }
2738 binder_proc_unlock(proc);
2700 } else { 2739 } else {
2701 mutex_lock(&context->context_mgr_node_lock); 2740 mutex_lock(&context->context_mgr_node_lock);
2702 target_node = context->binder_context_mgr_node; 2741 target_node = context->binder_context_mgr_node;
2703 if (target_node == NULL) { 2742 if (target_node)
2743 target_node = binder_get_node_refs_for_txn(
2744 target_node, &target_proc,
2745 &return_error);
2746 else
2704 return_error = BR_DEAD_REPLY; 2747 return_error = BR_DEAD_REPLY;
2705 mutex_unlock(&context->context_mgr_node_lock);
2706 return_error_line = __LINE__;
2707 goto err_no_context_mgr_node;
2708 }
2709 binder_inc_node(target_node, 1, 0, NULL);
2710 mutex_unlock(&context->context_mgr_node_lock); 2748 mutex_unlock(&context->context_mgr_node_lock);
2711 } 2749 }
2712 e->to_node = target_node->debug_id; 2750 if (!target_node) {
2713 binder_node_lock(target_node); 2751 /*
2714 target_proc = target_node->proc; 2752 * return_error is set above
2715 if (target_proc == NULL) { 2753 */
2716 binder_node_unlock(target_node); 2754 return_error_param = -EINVAL;
2717 return_error = BR_DEAD_REPLY;
2718 return_error_line = __LINE__; 2755 return_error_line = __LINE__;
2719 goto err_dead_binder; 2756 goto err_dead_binder;
2720 } 2757 }
2721 binder_inner_proc_lock(target_proc); 2758 e->to_node = target_node->debug_id;
2722 target_proc->tmp_ref++;
2723 binder_inner_proc_unlock(target_proc);
2724 binder_node_unlock(target_node);
2725 if (security_binder_transaction(proc->tsk, 2759 if (security_binder_transaction(proc->tsk,
2726 target_proc->tsk) < 0) { 2760 target_proc->tsk) < 0) {
2727 return_error = BR_FAILED_REPLY; 2761 return_error = BR_FAILED_REPLY;
@@ -3071,6 +3105,8 @@ static void binder_transaction(struct binder_proc *proc,
3071 if (target_thread) 3105 if (target_thread)
3072 binder_thread_dec_tmpref(target_thread); 3106 binder_thread_dec_tmpref(target_thread);
3073 binder_proc_dec_tmpref(target_proc); 3107 binder_proc_dec_tmpref(target_proc);
3108 if (target_node)
3109 binder_dec_node_tmpref(target_node);
3074 /* 3110 /*
3075 * write barrier to synchronize with initialization 3111 * write barrier to synchronize with initialization
3076 * of log entry 3112 * of log entry
@@ -3090,6 +3126,8 @@ err_bad_parent:
3090err_copy_data_failed: 3126err_copy_data_failed:
3091 trace_binder_transaction_failed_buffer_release(t->buffer); 3127 trace_binder_transaction_failed_buffer_release(t->buffer);
3092 binder_transaction_buffer_release(target_proc, t->buffer, offp); 3128 binder_transaction_buffer_release(target_proc, t->buffer, offp);
3129 if (target_node)
3130 binder_dec_node_tmpref(target_node);
3093 target_node = NULL; 3131 target_node = NULL;
3094 t->buffer->transaction = NULL; 3132 t->buffer->transaction = NULL;
3095 binder_alloc_free_buf(&target_proc->alloc, t->buffer); 3133 binder_alloc_free_buf(&target_proc->alloc, t->buffer);
@@ -3104,13 +3142,14 @@ err_bad_call_stack:
3104err_empty_call_stack: 3142err_empty_call_stack:
3105err_dead_binder: 3143err_dead_binder:
3106err_invalid_target_handle: 3144err_invalid_target_handle:
3107err_no_context_mgr_node:
3108 if (target_thread) 3145 if (target_thread)
3109 binder_thread_dec_tmpref(target_thread); 3146 binder_thread_dec_tmpref(target_thread);
3110 if (target_proc) 3147 if (target_proc)
3111 binder_proc_dec_tmpref(target_proc); 3148 binder_proc_dec_tmpref(target_proc);
3112 if (target_node) 3149 if (target_node) {
3113 binder_dec_node(target_node, 1, 0); 3150 binder_dec_node(target_node, 1, 0);
3151 binder_dec_node_tmpref(target_node);
3152 }
3114 3153
3115 binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, 3154 binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
3116 "%d:%d transaction failed %d/%d, size %lld-%lld line %d\n", 3155 "%d:%d transaction failed %d/%d, size %lld-%lld line %d\n",
@@ -3623,12 +3662,6 @@ static void binder_stat_br(struct binder_proc *proc,
3623 } 3662 }
3624} 3663}
3625 3664
3626static int binder_has_thread_work(struct binder_thread *thread)
3627{
3628 return !binder_worklist_empty(thread->proc, &thread->todo) ||
3629 thread->looper_need_return;
3630}
3631
3632static int binder_put_node_cmd(struct binder_proc *proc, 3665static int binder_put_node_cmd(struct binder_proc *proc,
3633 struct binder_thread *thread, 3666 struct binder_thread *thread,
3634 void __user **ptrp, 3667 void __user **ptrp,
@@ -4258,12 +4291,9 @@ static unsigned int binder_poll(struct file *filp,
4258 4291
4259 binder_inner_proc_unlock(thread->proc); 4292 binder_inner_proc_unlock(thread->proc);
4260 4293
4261 if (binder_has_work(thread, wait_for_proc_work))
4262 return POLLIN;
4263
4264 poll_wait(filp, &thread->wait, wait); 4294 poll_wait(filp, &thread->wait, wait);
4265 4295
4266 if (binder_has_thread_work(thread)) 4296 if (binder_has_work(thread, wait_for_proc_work))
4267 return POLLIN; 4297 return POLLIN;
4268 4298
4269 return 0; 4299 return 0;
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
index 064f5e31ec55..c2819a3d58a6 100644
--- a/drivers/android/binder_alloc.c
+++ b/drivers/android/binder_alloc.c
@@ -215,17 +215,12 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
215 } 215 }
216 } 216 }
217 217
218 if (!vma && need_mm) 218 if (!vma && need_mm && mmget_not_zero(alloc->vma_vm_mm))
219 mm = get_task_mm(alloc->tsk); 219 mm = alloc->vma_vm_mm;
220 220
221 if (mm) { 221 if (mm) {
222 down_write(&mm->mmap_sem); 222 down_write(&mm->mmap_sem);
223 vma = alloc->vma; 223 vma = alloc->vma;
224 if (vma && mm != alloc->vma_vm_mm) {
225 pr_err("%d: vma mm and task mm mismatch\n",
226 alloc->pid);
227 vma = NULL;
228 }
229 } 224 }
230 225
231 if (!vma && need_mm) { 226 if (!vma && need_mm) {
@@ -565,7 +560,7 @@ static void binder_delete_free_buffer(struct binder_alloc *alloc,
565 binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, 560 binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC,
566 "%d: merge free, buffer %pK do not share page with %pK or %pK\n", 561 "%d: merge free, buffer %pK do not share page with %pK or %pK\n",
567 alloc->pid, buffer->data, 562 alloc->pid, buffer->data,
568 prev->data, next->data); 563 prev->data, next ? next->data : NULL);
569 binder_update_page_range(alloc, 0, buffer_start_page(buffer), 564 binder_update_page_range(alloc, 0, buffer_start_page(buffer),
570 buffer_start_page(buffer) + PAGE_SIZE, 565 buffer_start_page(buffer) + PAGE_SIZE,
571 NULL); 566 NULL);
@@ -720,6 +715,7 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
720 barrier(); 715 barrier();
721 alloc->vma = vma; 716 alloc->vma = vma;
722 alloc->vma_vm_mm = vma->vm_mm; 717 alloc->vma_vm_mm = vma->vm_mm;
718 mmgrab(alloc->vma_vm_mm);
723 719
724 return 0; 720 return 0;
725 721
@@ -795,6 +791,8 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc)
795 vfree(alloc->buffer); 791 vfree(alloc->buffer);
796 } 792 }
797 mutex_unlock(&alloc->mutex); 793 mutex_unlock(&alloc->mutex);
794 if (alloc->vma_vm_mm)
795 mmdrop(alloc->vma_vm_mm);
798 796
799 binder_alloc_debug(BINDER_DEBUG_OPEN_CLOSE, 797 binder_alloc_debug(BINDER_DEBUG_OPEN_CLOSE,
800 "%s: %d buffers %d, pages %d\n", 798 "%s: %d buffers %d, pages %d\n",
@@ -889,7 +887,6 @@ int binder_alloc_get_allocated_count(struct binder_alloc *alloc)
889void binder_alloc_vma_close(struct binder_alloc *alloc) 887void binder_alloc_vma_close(struct binder_alloc *alloc)
890{ 888{
891 WRITE_ONCE(alloc->vma, NULL); 889 WRITE_ONCE(alloc->vma, NULL);
892 WRITE_ONCE(alloc->vma_vm_mm, NULL);
893} 890}
894 891
895/** 892/**
@@ -926,9 +923,9 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
926 page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE; 923 page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE;
927 vma = alloc->vma; 924 vma = alloc->vma;
928 if (vma) { 925 if (vma) {
929 mm = get_task_mm(alloc->tsk); 926 if (!mmget_not_zero(alloc->vma_vm_mm))
930 if (!mm) 927 goto err_mmget;
931 goto err_get_task_mm_failed; 928 mm = alloc->vma_vm_mm;
932 if (!down_write_trylock(&mm->mmap_sem)) 929 if (!down_write_trylock(&mm->mmap_sem))
933 goto err_down_write_mmap_sem_failed; 930 goto err_down_write_mmap_sem_failed;
934 } 931 }
@@ -963,7 +960,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
963 960
964err_down_write_mmap_sem_failed: 961err_down_write_mmap_sem_failed:
965 mmput_async(mm); 962 mmput_async(mm);
966err_get_task_mm_failed: 963err_mmget:
967err_page_already_freed: 964err_page_already_freed:
968 mutex_unlock(&alloc->mutex); 965 mutex_unlock(&alloc->mutex);
969err_get_alloc_mutex_failed: 966err_get_alloc_mutex_failed:
@@ -1002,7 +999,6 @@ struct shrinker binder_shrinker = {
1002 */ 999 */
1003void binder_alloc_init(struct binder_alloc *alloc) 1000void binder_alloc_init(struct binder_alloc *alloc)
1004{ 1001{
1005 alloc->tsk = current->group_leader;
1006 alloc->pid = current->group_leader->pid; 1002 alloc->pid = current->group_leader->pid;
1007 mutex_init(&alloc->mutex); 1003 mutex_init(&alloc->mutex);
1008 INIT_LIST_HEAD(&alloc->buffers); 1004 INIT_LIST_HEAD(&alloc->buffers);
diff --git a/drivers/android/binder_alloc.h b/drivers/android/binder_alloc.h
index a3a3602c689c..2dd33b6df104 100644
--- a/drivers/android/binder_alloc.h
+++ b/drivers/android/binder_alloc.h
@@ -100,7 +100,6 @@ struct binder_lru_page {
100 */ 100 */
101struct binder_alloc { 101struct binder_alloc {
102 struct mutex mutex; 102 struct mutex mutex;
103 struct task_struct *tsk;
104 struct vm_area_struct *vma; 103 struct vm_area_struct *vma;
105 struct mm_struct *vma_vm_mm; 104 struct mm_struct *vma_vm_mm;
106 void *buffer; 105 void *buffer;