Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a26a536 authored by threader's avatar threader Committed by Bernhard Thoben
Browse files

Binder: Adjust commit da1b9564e85b1d7baf66cbfabcab27e183a1db63

Author: Minchan Kim <minchan@kernel.org>
Date:   Thu Aug 23 14:29:56 2018 +0900

    android: binder: fix the race mmap and alloc_new_buf_locked
parent ca4682db
Loading
Loading
Loading
Loading
+32 −6
Original line number Diff line number Diff line
@@ -336,6 +336,35 @@ err_no_vma:
	return vma ? -ENOMEM : -ESRCH;
}


static inline void binder_alloc_set_vma(struct binder_alloc *alloc,
		struct vm_area_struct *vma)
{
	if (vma)
		alloc->vma_vm_mm = vma->vm_mm;
	/*
	 * If we see alloc->vma is not NULL, buffer data structures set up
	 * completely. Look at smp_rmb side binder_alloc_get_vma.
	 * We also want to guarantee new alloc->vma_vm_mm is always visible
	 * if alloc->vma is set.
	 */
	smp_wmb();
	alloc->vma = vma;
}

static inline struct vm_area_struct *binder_alloc_get_vma(
		struct binder_alloc *alloc)
{
	struct vm_area_struct *vma = NULL;

	if (alloc->vma) {
		/* Look at description in binder_alloc_set_vma */
		smp_rmb();
		vma = alloc->vma;
	}
	return vma;
}

static void debug_low_async_space_locked(struct binder_alloc *alloc, int pid)
{
	/*
@@ -389,7 +418,7 @@ static struct binder_buffer *binder_alloc_new_buf_locked(
	size_t size, data_offsets_size;
	int ret;

	if (alloc->vma == NULL) {
	if (!binder_alloc_get_vma(alloc)) {
		pr_err("%d: binder_alloc_buf, no vma\n",
		       alloc->pid);
		return ERR_PTR(-ESRCH);
@@ -763,9 +792,7 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
	buffer->free = 1;
	binder_insert_free_buffer(alloc, buffer);
	alloc->free_async_space = alloc->buffer_size / 2;
	barrier();
	alloc->vma = vma;
	alloc->vma_vm_mm = vma->vm_mm;
	binder_alloc_set_vma(alloc, vma);
	/* Same as mmgrab() in later kernel versions */
	atomic_inc(&alloc->vma_vm_mm->mm_count);

@@ -908,8 +935,7 @@ int binder_alloc_get_allocated_count(struct binder_alloc *alloc)
 */
void binder_alloc_vma_close(struct binder_alloc *alloc)
{
	WRITE_ONCE(alloc->vma, NULL);
	WRITE_ONCE(alloc->vma_vm_mm, NULL);
	binder_alloc_set_vma(alloc, NULL);
}

/**