From 3064ec892323e7491a2fad4c282000f0973c3f56 Mon Sep 17 00:00:00 2001 From: Tejas Prajapati Date: Tue, 28 Dec 2021 15:23:19 +0530 Subject: [PATCH 1/5] msm: camera: reqmgr: reader writer locks to avoid memory faults Shared memory is initialized by CRM and used by other drivers; with CRM not active other drivers would fail to access the shared memory if memory manager is deinit. Reader Writer locks can prevent the open/close/ioctl calls from other drivers if CRM open/close is already being processed. Issue observed with the below sequence if drivers are opened from UMD directly without this change. CRM Open successful,ICP open successful, CRM close in progress, ICP open successful, mem mgr deinit and CRM close successful, ICP tries to access HFI memory and result in crash. This change helps to serialze the calls and prevents issue. CRs-Fixed: 3019488 Change-Id: I98554f952acd8febf65cc1144150e728a874171d Signed-off-by: Tejas Prajapati --- .../platform/msm/camera/cam_core/cam_subdev.c | 4 +- .../platform/msm/camera/cam_fd/cam_fd_dev.c | 7 +++- .../msm/camera/cam_icp/cam_icp_subdev.c | 5 ++- .../platform/msm/camera/cam_isp/cam_isp_dev.c | 6 ++- .../msm/camera/cam_jpeg/cam_jpeg_dev.c | 5 ++- .../msm/camera/cam_lrme/cam_lrme_dev.c | 7 +++- .../msm/camera/cam_req_mgr/cam_req_mgr_dev.c | 40 +++++++++++++++++++ .../msm/camera/cam_req_mgr/cam_req_mgr_util.c | 9 +++++ .../msm/camera/cam_req_mgr/cam_subdev.h | 24 ++++++++++- .../cam_actuator/cam_actuator_core.c | 7 +++- .../cam_csiphy/cam_csiphy_core.c | 8 +++- .../cam_eeprom/cam_eeprom_core.c | 6 ++- .../cam_flash/cam_flash_dev.c | 7 +++- .../cam_sensor_module/cam_ois/cam_ois_core.c | 6 ++- .../cam_sensor/cam_sensor_core.c | 5 +++ 15 files changed, 134 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_core/cam_subdev.c b/drivers/media/platform/msm/camera/cam_core/cam_subdev.c index d690508b85c0..bf732dd9a31e 100644 --- a/drivers/media/platform/msm/camera/cam_core/cam_subdev.c +++ b/drivers/media/platform/msm/camera/cam_core/cam_subdev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -60,8 +60,10 @@ static long cam_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, switch (cmd) { case VIDIOC_CAM_CONTROL: + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); rc = cam_node_handle_ioctl(node, (struct cam_control *) arg); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); break; default: CAM_ERR(CAM_CORE, "Invalid command %d for %s", cmd, diff --git a/drivers/media/platform/msm/camera/cam_fd/cam_fd_dev.c b/drivers/media/platform/msm/camera/cam_fd/cam_fd_dev.c index d5068ca26971..e8f74546a5ba 100644 --- a/drivers/media/platform/msm/camera/cam_fd/cam_fd_dev.c +++ b/drivers/media/platform/msm/camera/cam_fd/cam_fd_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -50,8 +50,11 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd, { struct cam_fd_dev *fd_dev = &g_fd_dev; + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + if (!fd_dev->probe_done) { CAM_ERR(CAM_FD, "FD Dev not initialized, fd_dev=%pK", fd_dev); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); return -ENODEV; } @@ -60,6 +63,8 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd, CAM_DBG(CAM_FD, "FD Subdev open count %d", fd_dev->open_cnt); mutex_unlock(&fd_dev->lock); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c b/drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c index 2ea7738cbdef..6d78cfbfcdcd 100644 --- a/drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c +++ b/drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -82,6 +82,8 @@ static int cam_icp_subdev_open(struct v4l2_subdev *sd, struct cam_node *node = v4l2_get_subdevdata(sd); int rc = 0; + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_icp_dev.icp_lock); if (g_icp_dev.open_cnt >= 1) { CAM_ERR(CAM_ICP, "ICP subdev is already opened"); @@ -104,6 +106,7 @@ static int cam_icp_subdev_open(struct v4l2_subdev *sd, g_icp_dev.open_cnt++; end: mutex_unlock(&g_icp_dev.icp_lock); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); return rc; } diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_dev.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_dev.c index c7e5d3836fda..847d81481c49 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_dev.c +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -59,10 +59,14 @@ static const struct of_device_id cam_isp_dt_match[] = { static int cam_isp_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_isp_dev.isp_mutex); g_isp_dev.open_cnt++; mutex_unlock(&g_isp_dev.isp_mutex); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_dev.c b/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_dev.c index 14892224e412..d772294848c6 100644 --- a/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_dev.c +++ b/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -57,11 +57,14 @@ static const struct of_device_id cam_jpeg_dt_match[] = { static int cam_jpeg_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); mutex_lock(&g_jpeg_dev.jpeg_mutex); g_jpeg_dev.open_cnt++; mutex_unlock(&g_jpeg_dev.jpeg_mutex); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_dev.c b/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_dev.c index 6b1250aea714..ac1b1b4adcc9 100644 --- a/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_dev.c +++ b/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -65,9 +65,12 @@ static int cam_lrme_dev_open(struct v4l2_subdev *sd, { struct cam_lrme_dev *lrme_dev = g_lrme_dev; + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + if (!lrme_dev) { CAM_ERR(CAM_LRME, "LRME Dev not initialized, dev=%pK", lrme_dev); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); return -ENODEV; } @@ -75,6 +78,8 @@ static int cam_lrme_dev_open(struct v4l2_subdev *sd, lrme_dev->open_cnt++; mutex_unlock(&lrme_dev->lock); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c index cb60ef4abb5a..d919c9ed4f33 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -33,6 +34,8 @@ static struct cam_req_mgr_device g_dev; struct kmem_cache *g_cam_req_mgr_timer_cachep; +DECLARE_RWSEM(rwsem_lock); + static int cam_media_device_setup(struct device *dev) { int rc; @@ -98,10 +101,28 @@ static void cam_v4l2_device_cleanup(void) g_dev.v4l2_dev = NULL; } +void cam_req_mgr_rwsem_read_op(enum cam_subdev_rwsem lock) +{ + if (lock == CAM_SUBDEV_LOCK) + down_read(&rwsem_lock); + else if (lock == CAM_SUBDEV_UNLOCK) + up_read(&rwsem_lock); +} + +static void cam_req_mgr_rwsem_write_op(enum cam_subdev_rwsem lock) +{ + if (lock == CAM_SUBDEV_LOCK) + down_write(&rwsem_lock); + else if (lock == CAM_SUBDEV_UNLOCK) + up_write(&rwsem_lock); +} + static int cam_req_mgr_open(struct file *filep) { int rc; + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_dev.cam_lock); if (g_dev.open_cnt >= 1) { rc = -EALREADY; @@ -127,12 +148,14 @@ static int cam_req_mgr_open(struct file *filep) } mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); return rc; mem_mgr_init_fail: v4l2_fh_release(filep); end: mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); return rc; } @@ -158,10 +181,13 @@ static int cam_req_mgr_close(struct file *filep) struct v4l2_fh *vfh = filep->private_data; struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_dev.cam_lock); if (g_dev.open_cnt <= 0) { mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); return -EINVAL; } @@ -188,6 +214,8 @@ static int cam_req_mgr_close(struct file *filep) cam_mem_mgr_deinit(); mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); + return 0; } @@ -536,6 +564,18 @@ void cam_register_subdev_fops(struct v4l2_file_operations *fops) } EXPORT_SYMBOL(cam_register_subdev_fops); +bool cam_req_mgr_is_open(void) +{ + bool crm_status; + + mutex_lock(&g_dev.cam_lock); + crm_status = g_dev.open_cnt ? true : false; + mutex_unlock(&g_dev.cam_lock); + + return crm_status; +} +EXPORT_SYMBOL(cam_req_mgr_is_open); + int cam_register_subdev(struct cam_subdev *csd) { struct v4l2_subdev *sd; diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_util.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_util.c index dda04f8e5164..f5c8a1fed1c4 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_util.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_util.c @@ -21,6 +21,7 @@ #include #include "cam_req_mgr_util.h" #include "cam_debug_util.h" +#include "cam_subdev.h" static struct cam_req_mgr_util_hdl_tbl *hdl_tbl; static DEFINE_SPINLOCK(hdl_tbl_lock); @@ -166,6 +167,14 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data) int idx; int rand = 0; int32_t handle; + bool crm_active; + + crm_active = cam_req_mgr_is_open(); + if (!crm_active) { + CAM_ERR(CAM_ICP, "CRM is not ACTIVE"); + spin_unlock_bh(&hdl_tbl_lock); + return -EINVAL; + } spin_lock_bh(&hdl_tbl_lock); if (!hdl_tbl) { diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_subdev.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_subdev.h index 8cd3214674d5..8a3790b29895 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_subdev.h +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_subdev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -23,6 +23,11 @@ #define CAM_SUBDEVICE_EVENT_MAX 30 +enum cam_subdev_rwsem { + CAM_SUBDEV_LOCK = 1, + CAM_SUBDEV_UNLOCK, +}; + /** * struct cam_subdev - describes a camera sub-device * @@ -112,4 +117,21 @@ int cam_register_subdev(struct cam_subdev *sd); */ int cam_unregister_subdev(struct cam_subdev *sd); +/** + * cam_req_mgr_rwsem_read_op() + * + * @brief : API to acquire read semaphore lock to platform framework. + * + * @lock : value indicates to lock or unlock the read lock + */ +void cam_req_mgr_rwsem_read_op(enum cam_subdev_rwsem lock); + +/** + * cam_req_mgr_is_open() + * + * @brief: This common utility function returns the crm active status + * + */ +bool cam_req_mgr_is_open(void); + #endif /* _CAM_SUBDEV_H_ */ diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c index 8519115cb437..a9c5ff7b5df1 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -748,6 +748,11 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl, actuator_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (actuator_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_ACTUATOR, "Can not create device handle"); + goto release_mutex; + } a_ctrl->bridge_intf.device_hdl = actuator_acq_dev.device_handle; a_ctrl->bridge_intf.session_hdl = actuator_acq_dev.session_handle; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index 9a1188537dd7..eea8886f0693 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -629,6 +629,12 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, csiphy_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (csiphy_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_CSIPHY, "Can not create device handle"); + goto release_mutex; + } + bridge_intf = &csiphy_dev->bridge_intf; bridge_intf->device_hdl[csiphy_acq_params.combo_mode] = csiphy_acq_dev.device_handle; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index 20976afd9c22..b6607613d775 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -360,6 +360,10 @@ static int32_t cam_eeprom_get_dev_handle(struct cam_eeprom_ctrl_t *e_ctrl, eeprom_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (eeprom_acq_dev.device_handle <= 0) { + CAM_ERR(CAM_EEPROM, "Can not create device handle"); + return -EFAULT; + } e_ctrl->bridge_intf.device_hdl = eeprom_acq_dev.device_handle; e_ctrl->bridge_intf.session_hdl = eeprom_acq_dev.session_handle; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c index cdd6a98d2bf1..54d33effb71d 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -74,6 +74,11 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl, flash_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (flash_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_FLASH, "Can not create device handle"); + goto release_mutex; + } fctrl->bridge_intf.device_hdl = flash_acq_dev.device_handle; fctrl->bridge_intf.session_hdl = diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c index 281b25482864..aea012bef794 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -93,6 +93,10 @@ static int cam_ois_get_dev_handle(struct cam_ois_ctrl_t *o_ctrl, ois_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (ois_acq_dev.device_handle <= 0) { + CAM_ERR(CAM_OIS, "Can not create device handle"); + return -EFAULT; + } o_ctrl->bridge_intf.device_hdl = ois_acq_dev.device_handle; o_ctrl->bridge_intf.session_hdl = ois_acq_dev.session_handle; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c index 2dbcaa6a7990..9db1f1cdeff2 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -723,6 +723,11 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, sensor_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (sensor_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_SENSOR, "Can not create device handle"); + goto release_mutex; + } s_ctrl->bridge_intf.device_hdl = sensor_acq_dev.device_handle; s_ctrl->bridge_intf.session_hdl = sensor_acq_dev.session_handle; From 6f0d0c6b69976c7d9b6f62fa01c16e1c46076fda Mon Sep 17 00:00:00 2001 From: Shravya Samala Date: Mon, 15 Nov 2021 14:40:42 +0530 Subject: [PATCH 2/5] msm: camera: cdm: Acquire mutex lock before accessing client data There is a chance of use after release of client data in cdm internal operation calls. Hence acquire mutex lock whenever accessing client data to avoid use after release scenario. CRs-Fixed: 3010261 Change-Id: I853854ada5e776b5d9fe34a05cd5fbd1001d68f7 Signed-off-by: Shravya Samala --- .../msm/camera_v3/cam_cdm/cam_cdm_core_common.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_core_common.c b/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_core_common.c index b1f4fe87e8fa..8c39d4295a2f 100644 --- a/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_core_common.c +++ b/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_core_common.c @@ -243,35 +243,34 @@ int cam_cdm_stream_ops_internal(void *hw_priv, return -EINVAL; core = (struct cam_cdm *)cdm_hw->core_info; + mutex_lock(&cdm_hw->hw_mutex); client_idx = CAM_CDM_GET_CLIENT_IDX(*handle); client = core->clients[client_idx]; if (!client) { CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client, *handle); + mutex_unlock(&cdm_hw->hw_mutex); return -EINVAL; } cam_cdm_get_client_refcount(client); if (*handle != client->handle) { CAM_ERR(CAM_CDM, "client id given handle=%x invalid", *handle); - cam_cdm_put_client_refcount(client); - return -EINVAL; + rc = -EINVAL; + goto end; } if (operation == true) { if (true == client->stream_on) { CAM_ERR(CAM_CDM, "Invalid CDM client is already streamed ON"); - cam_cdm_put_client_refcount(client); - return rc; + goto end; } } else { if (client->stream_on == false) { CAM_ERR(CAM_CDM, "Invalid CDM client is already streamed Off"); - cam_cdm_put_client_refcount(client); - return rc; + goto end; } } - mutex_lock(&cdm_hw->hw_mutex); if (operation == true) { if (!cdm_hw->open_count) { struct cam_ahb_vote ahb_vote; From 199b0eaef08bd95f10fdb29d964f9fc831085ee9 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Thu, 20 Jan 2022 15:00:05 +0530 Subject: [PATCH 3/5] diag: Ensure dci entry is valid before sending the packet Possibility of a race condition which can free the dci entry causing use after free case is prevented by adding the check for entry's validity. Change-Id: Ib436ffd16c266636d99885d6091eb1a6887737c7 Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_dci.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index cb9f4e46607e..abc5845376ad 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2022, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1619,7 +1619,6 @@ static int diag_send_dci_pkt(struct diag_cmd_reg_t *entry, return -EIO; } - mutex_lock(&driver->dci_mutex); /* prepare DCI packet */ header.start = CONTROL_CHAR; header.version = 1; @@ -1638,7 +1637,6 @@ static int diag_send_dci_pkt(struct diag_cmd_reg_t *entry, diag_update_pkt_buffer(driver->apps_dci_buf, write_len, DCI_PKT_TYPE); diag_update_sleeping_process(entry->pid, DCI_PKT_TYPE); - mutex_unlock(&driver->dci_mutex); return DIAG_DCI_NO_ERROR; } @@ -1658,7 +1656,6 @@ static int diag_send_dci_pkt(struct diag_cmd_reg_t *entry, entry->proc); status = DIAG_DCI_SEND_DATA_FAIL; } - mutex_unlock(&driver->dci_mutex); return status; } @@ -2130,8 +2127,11 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) if (temp_entry) { reg_item = container_of(temp_entry, struct diag_cmd_reg_t, entry); - ret = diag_send_dci_pkt(reg_item, req_buf, req_len, + mutex_lock(&driver->dci_mutex); + if (req_entry) + ret = diag_send_dci_pkt(reg_item, req_buf, req_len, req_entry->tag); + mutex_unlock(&driver->dci_mutex); } else { DIAG_LOG(DIAG_DEBUG_DCI, "Command not found: %02x %02x %02x\n", reg_entry.cmd_code, reg_entry.subsys_id, From c12814514f2b9651927351901f95decbe3dc595b Mon Sep 17 00:00:00 2001 From: Tejas Prajapati Date: Tue, 28 Dec 2021 16:02:43 +0530 Subject: [PATCH 4/5] msm: camera: reqmgr: reader writer locks to avoid memory faults Shared memory is initialized by CRM and used by other drivers; with CRM not active other drivers would fail to access the shared memory if memory manager is deinit. Reader Writer locks can prevent the open/close/ioctl calls from other drivers if CRM open/close is already being processed. Issue observed with the below sequence if drivers are opened from UMD directly without this change. CRM Open successful,ICP open successful, CRM close in progress, ICP open successful, mem mgr deinit and CRM close successful, ICP tries to access HFI memory and result in crash. This change helps to serialze the calls and prevents issue. CRs-Fixed: 3019488 Change-Id: I9e73de1a7f68431e0b20125c75799ec308b010dd Signed-off-by: Tejas Prajapati --- .../msm/camera_v3/cam_core/cam_subdev.c | 4 +- .../msm/camera_v3/cam_fd/cam_fd_dev.c | 7 +++- .../msm/camera_v3/cam_icp/cam_icp_subdev.c | 5 ++- .../msm/camera_v3/cam_isp/cam_isp_dev.c | 6 ++- .../msm/camera_v3/cam_jpeg/cam_jpeg_dev.c | 5 ++- .../msm/camera_v3/cam_lrme/cam_lrme_dev.c | 7 +++- .../camera_v3/cam_req_mgr/cam_req_mgr_dev.c | 40 +++++++++++++++++++ .../camera_v3/cam_req_mgr/cam_req_mgr_util.c | 9 +++++ .../msm/camera_v3/cam_req_mgr/cam_subdev.h | 24 ++++++++++- .../cam_actuator/cam_actuator_core.c | 5 +++ .../cam_csiphy/cam_csiphy_core.c | 8 +++- .../cam_eeprom/cam_eeprom_core.c | 6 ++- .../cam_flash/cam_flash_dev.c | 7 +++- .../cam_sensor_module/cam_ois/cam_ois_core.c | 4 ++ .../cam_sensor/cam_sensor_core.c | 5 +++ 15 files changed, 132 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_subdev.c b/drivers/media/platform/msm/camera_v3/cam_core/cam_subdev.c index 6511a188e3b8..bf732dd9a31e 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_subdev.c +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_subdev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -60,8 +60,10 @@ static long cam_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, switch (cmd) { case VIDIOC_CAM_CONTROL: + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); rc = cam_node_handle_ioctl(node, (struct cam_control *) arg); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); break; default: CAM_ERR(CAM_CORE, "Invalid command %d for %s", cmd, diff --git a/drivers/media/platform/msm/camera_v3/cam_fd/cam_fd_dev.c b/drivers/media/platform/msm/camera_v3/cam_fd/cam_fd_dev.c index d5068ca26971..e8f74546a5ba 100644 --- a/drivers/media/platform/msm/camera_v3/cam_fd/cam_fd_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_fd/cam_fd_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -50,8 +50,11 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd, { struct cam_fd_dev *fd_dev = &g_fd_dev; + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + if (!fd_dev->probe_done) { CAM_ERR(CAM_FD, "FD Dev not initialized, fd_dev=%pK", fd_dev); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); return -ENODEV; } @@ -60,6 +63,8 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd, CAM_DBG(CAM_FD, "FD Subdev open count %d", fd_dev->open_cnt); mutex_unlock(&fd_dev->lock); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_subdev.c b/drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_subdev.c index 699ad5f2a0b4..0e352703a0bc 100644 --- a/drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_subdev.c +++ b/drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_subdev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -82,6 +82,8 @@ static int cam_icp_subdev_open(struct v4l2_subdev *sd, struct cam_node *node = v4l2_get_subdevdata(sd); int rc = 0; + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_icp_dev.icp_lock); if (g_icp_dev.open_cnt >= 1) { CAM_ERR(CAM_ICP, "ICP subdev is already opened"); @@ -104,6 +106,7 @@ static int cam_icp_subdev_open(struct v4l2_subdev *sd, g_icp_dev.open_cnt++; end: mutex_unlock(&g_icp_dev.icp_lock); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); return rc; } diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_dev.c b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_dev.c index d8b7a7b5e73e..9d964364072c 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -58,10 +58,14 @@ static const struct of_device_id cam_isp_dt_match[] = { static int cam_isp_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_isp_dev.isp_mutex); g_isp_dev.open_cnt++; mutex_unlock(&g_isp_dev.isp_mutex); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/drivers/media/platform/msm/camera_v3/cam_jpeg/cam_jpeg_dev.c b/drivers/media/platform/msm/camera_v3/cam_jpeg/cam_jpeg_dev.c index 14892224e412..d772294848c6 100644 --- a/drivers/media/platform/msm/camera_v3/cam_jpeg/cam_jpeg_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_jpeg/cam_jpeg_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -57,11 +57,14 @@ static const struct of_device_id cam_jpeg_dt_match[] = { static int cam_jpeg_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); mutex_lock(&g_jpeg_dev.jpeg_mutex); g_jpeg_dev.open_cnt++; mutex_unlock(&g_jpeg_dev.jpeg_mutex); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/drivers/media/platform/msm/camera_v3/cam_lrme/cam_lrme_dev.c b/drivers/media/platform/msm/camera_v3/cam_lrme/cam_lrme_dev.c index 6b1250aea714..ac1b1b4adcc9 100644 --- a/drivers/media/platform/msm/camera_v3/cam_lrme/cam_lrme_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_lrme/cam_lrme_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -65,9 +65,12 @@ static int cam_lrme_dev_open(struct v4l2_subdev *sd, { struct cam_lrme_dev *lrme_dev = g_lrme_dev; + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + if (!lrme_dev) { CAM_ERR(CAM_LRME, "LRME Dev not initialized, dev=%pK", lrme_dev); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); return -ENODEV; } @@ -75,6 +78,8 @@ static int cam_lrme_dev_open(struct v4l2_subdev *sd, lrme_dev->open_cnt++; mutex_unlock(&lrme_dev->lock); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c index 5d4d9fcc47ab..fe62f630376f 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -33,6 +34,8 @@ static struct cam_req_mgr_device g_dev; struct kmem_cache *g_cam_req_mgr_timer_cachep; +DECLARE_RWSEM(rwsem_lock); + static int cam_media_device_setup(struct device *dev) { int rc; @@ -98,10 +101,28 @@ static void cam_v4l2_device_cleanup(void) g_dev.v4l2_dev = NULL; } +void cam_req_mgr_rwsem_read_op(enum cam_subdev_rwsem lock) +{ + if (lock == CAM_SUBDEV_LOCK) + down_read(&rwsem_lock); + else if (lock == CAM_SUBDEV_UNLOCK) + up_read(&rwsem_lock); +} + +static void cam_req_mgr_rwsem_write_op(enum cam_subdev_rwsem lock) +{ + if (lock == CAM_SUBDEV_LOCK) + down_write(&rwsem_lock); + else if (lock == CAM_SUBDEV_UNLOCK) + up_write(&rwsem_lock); +} + static int cam_req_mgr_open(struct file *filep) { int rc; + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_dev.cam_lock); if (g_dev.open_cnt >= 1) { rc = -EALREADY; @@ -127,12 +148,14 @@ static int cam_req_mgr_open(struct file *filep) } mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); return rc; mem_mgr_init_fail: v4l2_fh_release(filep); end: mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); return rc; } @@ -158,10 +181,13 @@ static int cam_req_mgr_close(struct file *filep) struct v4l2_fh *vfh = filep->private_data; struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_dev.cam_lock); if (g_dev.open_cnt <= 0) { mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); return -EINVAL; } @@ -188,6 +214,8 @@ static int cam_req_mgr_close(struct file *filep) cam_mem_mgr_deinit(); mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); + return 0; } @@ -586,6 +614,18 @@ void cam_register_subdev_fops(struct v4l2_file_operations *fops) } EXPORT_SYMBOL(cam_register_subdev_fops); +bool cam_req_mgr_is_open(void) +{ + bool crm_status; + + mutex_lock(&g_dev.cam_lock); + crm_status = g_dev.open_cnt ? true : false; + mutex_unlock(&g_dev.cam_lock); + + return crm_status; +} +EXPORT_SYMBOL(cam_req_mgr_is_open); + int cam_register_subdev(struct cam_subdev *csd) { struct v4l2_subdev *sd; diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c index 8c2a3d424ccd..343ae97bad42 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c @@ -21,6 +21,7 @@ #include #include "cam_req_mgr_util.h" #include "cam_debug_util.h" +#include "cam_subdev.h" static struct cam_req_mgr_util_hdl_tbl *hdl_tbl; static DEFINE_SPINLOCK(hdl_tbl_lock); @@ -166,6 +167,14 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data) int idx; int rand = 0; int32_t handle; + bool crm_active; + + crm_active = cam_req_mgr_is_open(); + if (!crm_active) { + CAM_ERR(CAM_ICP, "CRM is not ACTIVE"); + spin_unlock_bh(&hdl_tbl_lock); + return -EINVAL; + } spin_lock_bh(&hdl_tbl_lock); if (!hdl_tbl) { diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_subdev.h b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_subdev.h index c9fa904e64af..8a3790b29895 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_subdev.h +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_subdev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -23,6 +23,11 @@ #define CAM_SUBDEVICE_EVENT_MAX 30 +enum cam_subdev_rwsem { + CAM_SUBDEV_LOCK = 1, + CAM_SUBDEV_UNLOCK, +}; + /** * struct cam_subdev - describes a camera sub-device * @@ -112,4 +117,21 @@ int cam_register_subdev(struct cam_subdev *sd); */ int cam_unregister_subdev(struct cam_subdev *sd); +/** + * cam_req_mgr_rwsem_read_op() + * + * @brief : API to acquire read semaphore lock to platform framework. + * + * @lock : value indicates to lock or unlock the read lock + */ +void cam_req_mgr_rwsem_read_op(enum cam_subdev_rwsem lock); + +/** + * cam_req_mgr_is_open() + * + * @brief: This common utility function returns the crm active status + * + */ +bool cam_req_mgr_is_open(void); + #endif /* _CAM_SUBDEV_H_ */ diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c index 51375809b6e2..ac89ab02b974 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -790,6 +790,11 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl, bridge_params.dev_id = CAM_ACTUATOR; actuator_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (actuator_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_ACTUATOR, "Can not create device handle"); + goto release_mutex; + } a_ctrl->bridge_intf.device_hdl = actuator_acq_dev.device_handle; a_ctrl->bridge_intf.session_hdl = actuator_acq_dev.session_handle; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index b8605596aa6c..b269b431be0c 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -738,6 +738,12 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, csiphy_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (csiphy_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_CSIPHY, "Can not create device handle"); + goto release_mutex; + } + bridge_intf = &csiphy_dev->bridge_intf; bridge_intf->device_hdl[csiphy_acq_params.combo_mode] = csiphy_acq_dev.device_handle; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index bcd3823a357c..53a84bcd24ce 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -360,6 +360,10 @@ static int32_t cam_eeprom_get_dev_handle(struct cam_eeprom_ctrl_t *e_ctrl, bridge_params.dev_id = CAM_EEPROM; eeprom_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (eeprom_acq_dev.device_handle <= 0) { + CAM_ERR(CAM_EEPROM, "Can not create device handle"); + return -EFAULT; + } e_ctrl->bridge_intf.device_hdl = eeprom_acq_dev.device_handle; e_ctrl->bridge_intf.session_hdl = eeprom_acq_dev.session_handle; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c index f4c9d254df7c..7fde31ac798c 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -74,6 +74,11 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl, bridge_params.dev_id = CAM_FLASH; flash_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (flash_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_FLASH, "Can not create device handle"); + goto release_mutex; + } fctrl->bridge_intf.device_hdl = flash_acq_dev.device_handle; fctrl->bridge_intf.session_hdl = diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c index c8d3a1a0a49b..d46d76d6b19e 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c @@ -94,6 +94,10 @@ static int cam_ois_get_dev_handle(struct cam_ois_ctrl_t *o_ctrl, bridge_params.dev_id = CAM_OIS; ois_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (ois_acq_dev.device_handle <= 0) { + CAM_ERR(CAM_OIS, "Can not create device handle"); + return -EFAULT; + } o_ctrl->bridge_intf.device_hdl = ois_acq_dev.device_handle; o_ctrl->bridge_intf.session_hdl = ois_acq_dev.session_handle; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c index 0ed36d143265..7f372bf9bd88 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -800,6 +800,11 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, bridge_params.dev_id = CAM_SENSOR; sensor_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (sensor_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_SENSOR, "Can not create device handle"); + goto release_mutex; + } s_ctrl->bridge_intf.device_hdl = sensor_acq_dev.device_handle; s_ctrl->bridge_intf.session_hdl = sensor_acq_dev.session_handle; From 4d3d93cb5e83e8c206bb4489abce028a87e9a0f3 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Wed, 2 Feb 2022 11:42:11 +0530 Subject: [PATCH 5/5] diag: Validate the dci client before sending dci packet Ensure dci client's tag used is a valid one by validating against its status before sending the dci packet to client. Change-Id: Ia673e8b548e441eb907820dc395c22b7f1b75d10 Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_dci.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index abc5845376ad..f2adbb728646 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -1981,12 +1981,13 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) { int ret = DIAG_DCI_TABLE_ERR; int common_cmd = 0, header_len = 0; + int req_tag = 0; struct diag_pkt_header_t *header = NULL; unsigned char *temp = buf; unsigned char *req_buf = NULL; uint8_t retry_count = 0, max_retries = 3; uint32_t read_len = 0, req_len = len; - struct dci_pkt_req_entry_t *req_entry = NULL; + struct dci_pkt_req_entry_t *req_entry = NULL, *test_entry = NULL; struct diag_dci_client_tbl *dci_entry = NULL; struct dci_pkt_req_t req_hdr; struct diag_cmd_reg_t *reg_item; @@ -2090,6 +2091,7 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) mutex_unlock(&driver->dci_mutex); return DIAG_DCI_NO_REG; } + req_tag = req_entry->tag; mutex_unlock(&driver->dci_mutex); /* @@ -2097,14 +2099,14 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) * remote processor */ if (dci_entry->client_info.token > 0) { - ret = diag_send_dci_pkt_remote(req_buf, req_len, req_entry->tag, + ret = diag_send_dci_pkt_remote(req_buf, req_len, req_tag, dci_entry->client_info.token); return ret; } /* Check if it is a dedicated Apps command */ ret = diag_dci_process_apps_pkt(header, req_buf, req_len, - req_entry->tag, header_len); + req_tag, header_len); if ((ret == DIAG_DCI_NO_ERROR && !common_cmd) || ret < 0) return ret; @@ -2128,9 +2130,12 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) reg_item = container_of(temp_entry, struct diag_cmd_reg_t, entry); mutex_lock(&driver->dci_mutex); - if (req_entry) + test_entry = diag_dci_get_request_entry(req_tag); + if (test_entry) ret = diag_send_dci_pkt(reg_item, req_buf, req_len, - req_entry->tag); + test_entry->tag); + else + ret = -EIO; mutex_unlock(&driver->dci_mutex); } else { DIAG_LOG(DIAG_DEBUG_DCI, "Command not found: %02x %02x %02x\n",