Эх сурвалжийг харах

msm: camera: core: validation of session/device handle

This change is to validate session and device handle.
Also, checks whether the device handle belongs to
correct session handle or not.

CRs-Fixed: 3350595
Change-Id: If1e06607ccaa99d3288ddca6a263d54315b14caa
Signed-off-by: Karthik Dillibabu <[email protected]>
Karthik Dillibabu 2 жил өмнө
parent
commit
64f96eb4ea

+ 79 - 58
drivers/cam_core/cam_node.c

@@ -125,6 +125,13 @@ static int __cam_node_handle_acquire_dev(struct cam_node *node,
 	}
 
 	ctx->last_flush_req = 0;
+
+	rc = cam_handle_validate(acquire->session_handle, acquire->session_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid session handle for acquire dev");
+		goto free_ctx;
+	}
+
 	rc = cam_context_handle_acquire_dev(ctx, acquire);
 	if (rc) {
 		CAM_ERR(CAM_CORE, "Acquire device failed for node %s",
@@ -161,14 +168,16 @@ static int __cam_node_handle_acquire_hw_v1(struct cam_node *node,
 	if (!acquire)
 		return -EINVAL;
 
-	if (acquire->dev_handle <= 0) {
-		CAM_ERR(CAM_CORE, "Invalid device handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(acquire->session_handle, acquire->session_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid session handle for context");
+		return rc;
 	}
 
-	if (acquire->session_handle <= 0) {
-		CAM_ERR(CAM_CORE, "Invalid session handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(acquire->session_handle, acquire->dev_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid device handle for context");
+		return rc;
 	}
 
 	ctx = (struct cam_context *)cam_get_device_priv(acquire->dev_handle);
@@ -207,14 +216,16 @@ static int __cam_node_handle_acquire_hw_v2(struct cam_node *node,
 	if (!acquire)
 		return -EINVAL;
 
-	if (acquire->dev_handle <= 0) {
-		CAM_ERR(CAM_CORE, "Invalid device handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(acquire->session_handle, acquire->session_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid session handle for context");
+		return rc;
 	}
 
-	if (acquire->session_handle <= 0) {
-		CAM_ERR(CAM_CORE, "Invalid session handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(acquire->session_handle, acquire->dev_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid device handle for context");
+		return rc;
 	}
 
 	ctx = (struct cam_context *)cam_get_device_priv(acquire->dev_handle);
@@ -247,14 +258,16 @@ static int __cam_node_handle_start_dev(struct cam_node *node,
 	if (!start)
 		return -EINVAL;
 
-	if (start->dev_handle <= 0) {
-		CAM_ERR(CAM_CORE, "Invalid device handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(start->session_handle, start->session_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid session handle for context");
+		return rc;
 	}
 
-	if (start->session_handle <= 0) {
-		CAM_ERR(CAM_CORE, "Invalid session handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(start->session_handle, start->dev_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid device handle for context");
+		return rc;
 	}
 
 	ctx = (struct cam_context *)cam_get_device_priv(start->dev_handle);
@@ -286,14 +299,16 @@ static int __cam_node_handle_stop_dev(struct cam_node *node,
 	if (!stop)
 		return -EINVAL;
 
-	if (stop->dev_handle <= 0) {
-		CAM_ERR(CAM_CORE, "Invalid device handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(stop->session_handle, stop->session_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid session handle for context");
+		return rc;
 	}
 
-	if (stop->session_handle <= 0) {
-		CAM_ERR(CAM_CORE, "Invalid session handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(stop->session_handle, stop->dev_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid device handle for context");
+		return rc;
 	}
 
 	ctx = (struct cam_context *)cam_get_device_priv(stop->dev_handle);
@@ -325,14 +340,16 @@ static int __cam_node_handle_config_dev(struct cam_node *node,
 	if (!config)
 		return -EINVAL;
 
-	if (config->dev_handle <= 0) {
-		CAM_ERR(CAM_CORE, "Invalid device handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(config->session_handle, config->session_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid session handle for context");
+		return rc;
 	}
 
-	if (config->session_handle <= 0) {
-		CAM_ERR(CAM_CORE, "Invalid session handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(config->session_handle, config->dev_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid device handle for context");
+		return rc;
 	}
 
 	ctx = (struct cam_context *)cam_get_device_priv(config->dev_handle);
@@ -369,16 +386,16 @@ static int __cam_node_handle_flush_dev(struct cam_node *node,
 	if (!flush)
 		return -EINVAL;
 
-	if (flush->dev_handle <= 0) {
-		CAM_ERR_RATE_LIMIT(CAM_CORE,
-			"Invalid device handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(flush->session_handle, flush->session_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid session handle for context");
+		return rc;
 	}
 
-	if (flush->session_handle <= 0) {
-		CAM_ERR_RATE_LIMIT(CAM_CORE,
-			"Invalid session handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(flush->session_handle, flush->dev_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid device handle for context");
+		return rc;
 	}
 
 	ctx = (struct cam_context *)cam_get_device_priv(flush->dev_handle);
@@ -413,14 +430,16 @@ static int __cam_node_handle_release_dev(struct cam_node *node,
 	if (!release)
 		return -EINVAL;
 
-	if (release->dev_handle <= 0) {
-		CAM_ERR(CAM_CORE, "Invalid device handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(release->session_handle, release->session_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid session handle for context");
+		return rc;
 	}
 
-	if (release->session_handle <= 0) {
-		CAM_ERR(CAM_CORE, "Invalid session handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(release->session_handle, release->dev_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid device handle for context");
+		return rc;
 	}
 
 	ctx = (struct cam_context *)cam_get_device_priv(release->dev_handle);
@@ -474,16 +493,16 @@ static int __cam_node_handle_dump_dev(struct cam_node *node,
 	if (!dump)
 		return -EINVAL;
 
-	if (dump->dev_handle <= 0) {
-		CAM_ERR_RATE_LIMIT(CAM_CORE,
-			"Invalid device handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(dump->session_handle, dump->session_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid session handle for context");
+		return rc;
 	}
 
-	if (dump->session_handle <= 0) {
-		CAM_ERR_RATE_LIMIT(CAM_CORE,
-			"Invalid session handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(dump->session_handle, dump->dev_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid device handle for context");
+		return rc;
 	}
 
 	ctx = (struct cam_context *)cam_get_device_priv(dump->dev_handle);
@@ -511,14 +530,16 @@ static int __cam_node_handle_release_hw_v1(struct cam_node *node,
 	if (!release)
 		return -EINVAL;
 
-	if (release->dev_handle <= 0) {
-		CAM_ERR(CAM_CORE, "Invalid device handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(release->session_handle, release->session_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid session handle for context");
+		return rc;
 	}
 
-	if (release->session_handle <= 0) {
-		CAM_ERR(CAM_CORE, "Invalid session handle for context");
-		return -EINVAL;
+	rc = cam_handle_validate(release->session_handle, release->dev_handle);
+	if (rc) {
+		CAM_ERR(CAM_CORE, "Invalid device handle for context");
+		return rc;
 	}
 
 	ctx = (struct cam_context *)cam_get_device_priv(release->dev_handle);

+ 39 - 1
drivers/cam_req_mgr/cam_req_mgr_util.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #define pr_fmt(fmt) "CAM-REQ-MGR_UTIL %s:%d " fmt, __func__, __LINE__
@@ -83,6 +83,44 @@ int cam_req_mgr_util_deinit(void)
 	return 0;
 }
 
+int cam_handle_validate(int32_t session_hdl, int32_t handle)
+{
+	int idx, rc = 0;
+
+	spin_lock_bh(&hdl_tbl_lock);
+	if (!hdl_tbl) {
+		CAM_ERR(CAM_CRM, "Hdl tbl is NULL");
+		rc = -EINVAL;
+		goto out;
+	}
+
+	idx = CAM_REQ_MGR_GET_HDL_IDX(handle);
+	if (idx < 0 || idx >= CAM_REQ_MGR_MAX_HANDLES_V2) {
+		CAM_ERR(CAM_CRM, "Invalid index:%d for handle: 0x%x", idx, handle);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	if (hdl_tbl->hdl[idx].state != HDL_ACTIVE) {
+		CAM_ERR(CAM_CRM, "Invalid state:%d", hdl_tbl->hdl[idx].state);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	if (hdl_tbl->hdl[idx].session_hdl != session_hdl ||
+		hdl_tbl->hdl[idx].hdl_value != handle) {
+		CAM_ERR(CAM_CRM, "Exp ses_hdl: 0x%x ses_hdl: 0x%x Exp hdl: 0x%x hdl: 0x%x",
+			hdl_tbl->hdl[idx].session_hdl, session_hdl, hdl_tbl->hdl[idx].hdl_value,
+			handle);
+		rc = -EINVAL;
+		goto out;
+	}
+
+out:
+	spin_unlock_bh(&hdl_tbl_lock);
+	return rc;
+}
+
 int cam_req_mgr_util_free_hdls(void)
 {
 	int i = 0;

+ 12 - 0
drivers/cam_req_mgr/cam_req_mgr_util.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_REQ_MGR_UTIL_API_H_
@@ -81,6 +82,17 @@ struct cam_create_dev_hdl {
 	void *priv;
 };
 
+/**
+ * cam_handle_validate() - validate session/device handle
+ * @session_hdl: handle for a session
+ * @handle: handle for a session/device
+ *
+ * cam_req_mgr_core and KMD drivers use this function to
+ * validate session/device handle. Returns 0 on success,
+ * -EINVAL on failure.
+ */
+int cam_handle_validate(int32_t session_hdl, int32_t handle);
+
 /**
  * cam_create_session_hdl() - create a session handle
  * @priv: private data for a session handle