From 64f96eb4ead984db3d9e4bd989cef857ab44620d Mon Sep 17 00:00:00 2001 From: Karthik Dillibabu Date: Wed, 30 Nov 2022 12:34:48 +0530 Subject: [PATCH] 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 --- drivers/cam_core/cam_node.c | 137 ++++++++++++++----------- drivers/cam_req_mgr/cam_req_mgr_util.c | 40 +++++++- drivers/cam_req_mgr/cam_req_mgr_util.h | 12 +++ 3 files changed, 130 insertions(+), 59 deletions(-) diff --git a/drivers/cam_core/cam_node.c b/drivers/cam_core/cam_node.c index e3dc1a03c7..0a670e9b00 100644 --- a/drivers/cam_core/cam_node.c +++ b/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); diff --git a/drivers/cam_req_mgr/cam_req_mgr_util.c b/drivers/cam_req_mgr/cam_req_mgr_util.c index e499f25c4c..5c2f114c87 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_util.c +++ b/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; diff --git a/drivers/cam_req_mgr/cam_req_mgr_util.h b/drivers/cam_req_mgr/cam_req_mgr_util.h index 0d0fec1f8e..4e5685f6c1 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_util.h +++ b/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