Unverified Commit d76d084d authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!1547 binder: fix UAF caused by faulty buffer cleanup

parents f2bd89f3 83bfcd1e
Loading
Loading
Loading
Loading
+20 −6
Original line number Diff line number Diff line
@@ -2267,24 +2267,23 @@ static void binder_deferred_fd_close(int fd)
static void binder_transaction_buffer_release(struct binder_proc *proc,
					      struct binder_thread *thread,
					      struct binder_buffer *buffer,
					      binder_size_t failed_at,
					      binder_size_t off_end_offset,
					      bool is_failure)
{
	int debug_id = buffer->debug_id;
	binder_size_t off_start_offset, buffer_offset, off_end_offset;
	binder_size_t off_start_offset, buffer_offset;

	binder_debug(BINDER_DEBUG_TRANSACTION,
		     "%d buffer release %d, size %zd-%zd, failed at %llx\n",
		     proc->pid, buffer->debug_id,
		     buffer->data_size, buffer->offsets_size,
		     (unsigned long long)failed_at);
		     (unsigned long long)off_end_offset);

	if (buffer->target_node)
		binder_dec_node(buffer->target_node, 1, 0);

	off_start_offset = ALIGN(buffer->data_size, sizeof(void *));
	off_end_offset = is_failure && failed_at ? failed_at :
				off_start_offset + buffer->offsets_size;

	for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
	     buffer_offset += sizeof(binder_size_t)) {
		struct binder_object_header *hdr;
@@ -2444,6 +2443,21 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
	}
}

/* Clean up all the objects in the buffer */
static inline void binder_release_entire_buffer(struct binder_proc *proc,
						struct binder_thread *thread,
						struct binder_buffer *buffer,
						bool is_failure)
{
	binder_size_t off_end_offset;

	off_end_offset = ALIGN(buffer->data_size, sizeof(void *));
	off_end_offset += buffer->offsets_size;

	binder_transaction_buffer_release(proc, thread, buffer,
					  off_end_offset, is_failure);
}

static int binder_translate_binder(struct flat_binder_object *fp,
				   struct binder_transaction *t,
				   struct binder_thread *thread)
@@ -3926,7 +3940,7 @@ binder_free_buf(struct binder_proc *proc,
		binder_node_inner_unlock(buf_node);
	}
	trace_binder_transaction_buffer_release(buffer);
	binder_transaction_buffer_release(proc, thread, buffer, 0, is_failure);
	binder_release_entire_buffer(proc, thread, buffer, is_failure);
	binder_alloc_free_buf(&proc->alloc, buffer);
}