aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/android/binder_alloc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-10-23 06:35:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-10-23 06:35:01 -0400
commit17e7637f5947284cd7f41c1b26ff8cbee9a794a4 (patch)
tree571c0ee5fec7224ba63dded321df818c88fd9994 /drivers/android/binder_alloc.c
parent5805992184f97b7797f24b74d511825f8992861e (diff)
parentae65c8510f3319dfb2114cc48d476b81232e27b3 (diff)
Merge tag 'char-misc-4.14-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver fixes from Greg KH: "Here are four small fixes for 4.14-rc6. Three of them are binder driver fixes for reported issues, and the last one is a hyperv driver bugfix. Nothing major, but good fixes to get into 4.14-final. All of these have been in linux-next with no reported issues" * tag 'char-misc-4.14-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: android: binder: Fix null ptr dereference in debug msg android: binder: Don't get mm from task vmbus: hvsock: add proper sync for vmbus_hvsock_device_unregister() binder: call poll_wait() unconditionally.
Diffstat (limited to 'drivers/android/binder_alloc.c')
-rw-r--r--drivers/android/binder_alloc.c24
1 files changed, 10 insertions, 14 deletions
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);