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

Commit 4581a896 authored by Arve Hjønnevåg's avatar Arve Hjønnevåg Committed by Amit Pundir
Browse files

ANDROID: binder: Add strong ref checks



Prevent using a binder_ref with only weak references where a strong
reference is required.

BUG: 30445380
Change-Id: I66c15b066808f28bd27bfe50fd0e03ff45a09fca
Signed-off-by: default avatarArve Hjønnevåg <arve@android.com>
parent 2320e1e8
Loading
Loading
Loading
Loading
+17 −9
Original line number Diff line number Diff line
@@ -1002,7 +1002,7 @@ static int binder_dec_node(struct binder_node *node, int strong, int internal)


static struct binder_ref *binder_get_ref(struct binder_proc *proc,
					 uint32_t desc)
					 uint32_t desc, bool need_strong_ref)
{
	struct rb_node *n = proc->refs_by_desc.rb_node;
	struct binder_ref *ref;
@@ -1010,13 +1010,17 @@ static struct binder_ref *binder_get_ref(struct binder_proc *proc,
	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;
}

@@ -1285,7 +1289,8 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
		} break;
		case BINDER_TYPE_HANDLE:
		case BINDER_TYPE_WEAK_HANDLE: {
			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
			struct binder_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 +1385,7 @@ static void binder_transaction(struct binder_proc *proc,
		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);
@@ -1589,7 +1594,8 @@ static void binder_transaction(struct binder_proc *proc,
		} break;
		case BINDER_TYPE_HANDLE:
		case BINDER_TYPE_WEAK_HANDLE: {
			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
			struct binder_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",
@@ -1800,7 +1806,9 @@ static int binder_thread_write(struct binder_proc *proc,
						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);
@@ -1996,7 +2004,7 @@ static int binder_thread_write(struct binder_proc *proc,
			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,