Merge tag 'LA.UM.9.12.1.r1-11000-SMxx50.QSSI12.0' of https://git.codelinaro.org/clo/la/platform/vendor/opensource/camera-kernel into android13-4.19-kona
"LA.UM.9.12.1.r1-11000-SMxx50.QSSI12.0" * tag 'LA.UM.9.12.1.r1-11000-SMxx50.QSSI12.0' of https://git.codelinaro.org/clo/la/platform/vendor/opensource/camera-kernel: msm: camera: isp: Copy the userdata in kernel to avoid TOCTOU Change-Id: I668492b6e074ef57366828c941256bd12911d6e1
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
@@ -5663,7 +5663,9 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
|
||||
break;
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG: {
|
||||
struct cam_isp_bw_config *bw_config;
|
||||
struct cam_isp_bw_config *bw_config_u;
|
||||
struct cam_isp_prepare_hw_update_data *prepare_hw_data;
|
||||
size_t bw_config_size;
|
||||
|
||||
CAM_WARN_RATE_LIMIT_CUSTOM(CAM_PERF, 300, 1,
|
||||
"Deprecated Blob TYPE_BW_CONFIG");
|
||||
@@ -5672,11 +5674,26 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bw_config = (struct cam_isp_bw_config *)blob_data;
|
||||
bw_config_u = (struct cam_isp_bw_config *)blob_data;
|
||||
|
||||
if (bw_config->num_rdi > CAM_IFE_RDI_NUM_MAX) {
|
||||
CAM_ERR(CAM_ISP, "Invalid num_rdi %u in bw config",
|
||||
if (bw_config_u->num_rdi > CAM_IFE_RDI_NUM_MAX || !bw_config_u->num_rdi) {
|
||||
CAM_ERR(CAM_ISP, "Invalid num_rdi %u in bw config, ctx_idx: %u",
|
||||
bw_config_u->num_rdi, ife_mgr_ctx->ctx_index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bw_config_size = sizeof(struct cam_isp_bw_config) + ((bw_config_u->num_rdi-1)*
|
||||
sizeof(struct cam_isp_bw_vote));
|
||||
|
||||
rc = cam_common_mem_kdup((void **)&bw_config, bw_config_u, bw_config_size);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Alloc and copy request bw_config failed");
|
||||
return rc;
|
||||
}
|
||||
if (bw_config_u->num_rdi != bw_config->num_rdi) {
|
||||
CAM_ERR(CAM_ISP, "num_rdi changed,userspace:%d, kernel:%d", bw_config_u->num_rdi,
|
||||
bw_config->num_rdi);
|
||||
cam_common_mem_free(bw_config);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -5689,6 +5706,7 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
|
||||
"Max size exceeded in bw config num_rdi:%u size per port:%lu",
|
||||
bw_config->num_rdi,
|
||||
sizeof(struct cam_isp_bw_vote));
|
||||
cam_common_mem_free(bw_config);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@@ -5701,12 +5719,14 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
|
||||
blob_size, sizeof(struct cam_isp_bw_config) +
|
||||
(bw_config->num_rdi - 1) *
|
||||
sizeof(struct cam_isp_bw_vote));
|
||||
cam_common_mem_free(bw_config);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!prepare || !prepare->priv ||
|
||||
(bw_config->usage_type >= CAM_IFE_HW_NUM_MAX)) {
|
||||
CAM_ERR(CAM_ISP, "Invalid inputs");
|
||||
cam_common_mem_free(bw_config);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -5717,11 +5737,13 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
|
||||
bw_config, sizeof(prepare_hw_data->bw_config[0]));
|
||||
prepare_hw_data->bw_config_version = CAM_ISP_BW_CONFIG_V1;
|
||||
prepare_hw_data->bw_config_valid[bw_config->usage_type] = true;
|
||||
cam_common_mem_free(bw_config);
|
||||
}
|
||||
break;
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2: {
|
||||
size_t bw_config_size = 0;
|
||||
struct cam_isp_bw_config_v2 *bw_config;
|
||||
struct cam_isp_bw_config_v2 *bw_config_u;
|
||||
struct cam_isp_prepare_hw_update_data *prepare_hw_data;
|
||||
|
||||
if (blob_size < sizeof(struct cam_isp_bw_config_v2)) {
|
||||
@@ -5729,12 +5751,28 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bw_config = (struct cam_isp_bw_config_v2 *)blob_data;
|
||||
bw_config_u = (struct cam_isp_bw_config_v2 *)blob_data;
|
||||
|
||||
if ((bw_config->num_paths > CAM_ISP_MAX_PER_PATH_VOTES) ||
|
||||
!bw_config->num_paths) {
|
||||
CAM_ERR(CAM_ISP, "Invalid num paths %d",
|
||||
if (bw_config_u->num_paths > CAM_ISP_MAX_PER_PATH_VOTES ||
|
||||
!bw_config_u->num_paths) {
|
||||
CAM_ERR(CAM_ISP, "Invalid num paths %d ctx_idx: %u",
|
||||
bw_config_u->num_paths, ife_mgr_ctx->ctx_index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bw_config_size = sizeof(struct cam_isp_bw_config_v2) + ((bw_config_u->num_paths-1)*
|
||||
sizeof(struct cam_axi_per_path_bw_vote));
|
||||
|
||||
rc = cam_common_mem_kdup((void **)&bw_config, bw_config_u, bw_config_size);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Alloc and copy request bw_config failed");
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (bw_config_u->num_paths != bw_config->num_paths) {
|
||||
CAM_ERR(CAM_ISP, "num_paths changed,userspace:%d, kernel:%d", bw_config_u->num_paths,
|
||||
bw_config->num_paths);
|
||||
cam_common_mem_free(bw_config);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -5749,6 +5787,7 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
|
||||
bw_config->num_paths - 1,
|
||||
sizeof(
|
||||
struct cam_axi_per_path_bw_vote));
|
||||
cam_common_mem_free(bw_config);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@@ -5762,12 +5801,14 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
|
||||
blob_size, bw_config->num_paths,
|
||||
sizeof(struct cam_isp_bw_config_v2),
|
||||
sizeof(struct cam_axi_per_path_bw_vote));
|
||||
cam_common_mem_free(bw_config);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!prepare || !prepare->priv ||
|
||||
(bw_config->usage_type >= CAM_IFE_HW_NUM_MAX)) {
|
||||
CAM_ERR(CAM_ISP, "Invalid inputs");
|
||||
cam_common_mem_free(bw_config);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -5785,6 +5826,7 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
|
||||
|
||||
prepare_hw_data->bw_config_version = CAM_ISP_BW_CONFIG_V2;
|
||||
prepare_hw_data->bw_config_valid[bw_config->usage_type] = true;
|
||||
cam_common_mem_free(bw_config);
|
||||
}
|
||||
break;
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG: {
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include "cam_common_util.h"
|
||||
#include "cam_debug_util.h"
|
||||
@@ -48,3 +50,36 @@ uint32_t cam_common_util_remove_duplicate_arr(int32_t *arr, uint32_t num)
|
||||
|
||||
return wr_idx;
|
||||
}
|
||||
|
||||
int cam_common_mem_kdup(void **dst,
|
||||
void *src, size_t size)
|
||||
{
|
||||
gfp_t flag = GFP_KERNEL;
|
||||
|
||||
if (!src || !dst || !size) {
|
||||
CAM_ERR(CAM_UTIL, "Invalid params src: %pK dst: %pK size: %u",
|
||||
src, dst, size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!in_task())
|
||||
flag = GFP_ATOMIC;
|
||||
|
||||
*dst = kvzalloc(size, flag);
|
||||
if (!*dst) {
|
||||
CAM_ERR(CAM_UTIL, "Failed to allocate memory with size: %u", size);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(*dst, src, size);
|
||||
CAM_DBG(CAM_UTIL, "Allocate and copy memory with size: %u", size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(cam_common_mem_kdup);
|
||||
|
||||
void cam_common_mem_free(void *memory)
|
||||
{
|
||||
kvfree(memory);
|
||||
}
|
||||
EXPORT_SYMBOL(cam_common_mem_free);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_COMMON_UTIL_H_
|
||||
@@ -64,4 +65,22 @@ int cam_common_util_get_string_index(const char **strings,
|
||||
uint32_t cam_common_util_remove_duplicate_arr(int32_t *array,
|
||||
uint32_t num);
|
||||
|
||||
/**
|
||||
* @brief: Memory alloc and copy
|
||||
*
|
||||
* @dst: Address of destination address of memory
|
||||
* @src: Source address of memory
|
||||
* @size: Length of memory
|
||||
*
|
||||
* @return 0 if success in register non-zero if failes
|
||||
*/
|
||||
int cam_common_mem_kdup(void **dst, void *src, size_t size);
|
||||
|
||||
/**
|
||||
* @brief: Free the memory
|
||||
*
|
||||
* @memory: Address of memory
|
||||
*/
|
||||
void cam_common_mem_free(void *memory);
|
||||
|
||||
#endif /* _CAM_COMMON_UTIL_H_ */
|
||||
|
||||
Reference in New Issue
Block a user