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

Commit 1efc1b29 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: synx: validate external callback"

parents 29f8698e abcc12b9
Loading
Loading
Loading
Loading
+45 −1
Original line number Diff line number Diff line
@@ -17,6 +17,40 @@

struct synx_device *synx_dev;

static int synx_validate_callback(
	struct synx_coredata *synx_obj,
	s32 sync_id,
	void *data)
{
	u32 i;
	int rc = -EINVAL;
	struct synx_bind_desc *bind_desc = NULL;

	if (!synx_obj)
		return -EINVAL;

	/* need to validate the callback
	 * as it could be dispatched and/or
	 * scheduled late, after the handle
	 * has been released and re-allocated.
	 */
	spin_lock_bh(&synx_obj->lock);
	for (i = 0; i < synx_obj->num_bound_synxs; i++) {
		bind_desc = &synx_obj->bound_synxs[i];
		if ((sync_id ==
			bind_desc->external_desc.id[0]) &&
			(data == bind_desc->external_data)) {
			rc = 0;
			pr_debug("callback validation success %d\n",
				sync_id);
			break;
		}
	}
	spin_unlock_bh(&synx_obj->lock);

	return rc;
}

void synx_external_callback(s32 sync_obj, int status, void *data)
{
	struct synx_coredata *synx_obj;
@@ -30,8 +64,11 @@ void synx_external_callback(s32 sync_obj, int status, void *data)
	}

	client = synx_get_client(bind_data->session_id);
	if (!client)
	if (!client) {
		pr_err("invalid payload content from sync external obj %d\n",
			sync_obj);
		goto free;
	}

	synx_obj = synx_util_acquire_object(client, bind_data->h_synx);
	if (!synx_obj) {
@@ -40,12 +77,19 @@ void synx_external_callback(s32 sync_obj, int status, void *data)
		goto fail;
	}

	if (synx_validate_callback(synx_obj, sync_obj, data)) {
		pr_err("[sess: %u] stale callback from external obj %d handle %d\n",
			client->id, sync_obj, bind_data->h_synx);
		goto release;
	}

	pr_debug("[sess: %u] external callback from %d on handle %d\n",
		client->id, sync_obj, bind_data->h_synx);
	if (synx_signal_core(synx_obj, status, true, sync_obj))
		pr_err("[sess: %u] signal callback failed for handle %d\n",
			client->id, bind_data->h_synx);

release:
	synx_util_release_object(client, bind_data->h_synx);
fail:
	synx_put_client(client);
+6 −7
Original line number Diff line number Diff line
@@ -140,17 +140,16 @@ void synx_util_object_destroy(struct synx_coredata *synx_obj)
		bind_ops = synx_util_get_bind_ops(type);
		rc = bind_ops->deregister_callback(
				synx_external_callback, data, sync_id);
		if (rc < 0)
		if (rc < 0) {
			pr_err("de-registration fail id: %d, type: %u, err: %d\n",
				sync_id, type, rc);
			continue;
		}

		/*
		 * release the memory allocated for external data.
		 * It is safe to release this memory as external cb
		 * has been already deregistered before this.
		 * even if deregistration fails, it implies the
		 * external fence might have been cleaned up already
		 * or in some bad state. Have to release cb data
		 * at this point or else will lead to memory leak.
		 * It is safe to release this memory
		 * only if deregistration is successful.
		 */
		kfree(data);
	}