Browse Source

Merge "msm: camera: core: Add buffer length check to prevent overflow" into camera-kernel.lnx.7.0

cheese Service 7 months ago
parent
commit
789bc32bbd
1 changed files with 35 additions and 31 deletions
  1. 35 31
      drivers/cam_core/cam_context_utils.c

+ 35 - 31
drivers/cam_core/cam_context_utils.c

@@ -1529,7 +1529,6 @@ static int cam_context_user_dump(struct cam_context *ctx,
 	struct cam_context_dump_header  *hdr;
 	uint8_t                         *dst;
 	uint64_t                        *addr, *start;
-	uint32_t                         min_len;
 	size_t                           buf_len, remain_len;
 	uintptr_t                        cpu_addr;
 	uint32_t                         local_len;
@@ -1556,38 +1555,16 @@ static int cam_context_user_dump(struct cam_context *ctx,
 		return -ENOSPC;
 	}
 
-	spin_lock_bh(&ctx->lock);
-	if (!list_empty(&ctx->active_req_list)) {
-		req = list_first_entry(&ctx->active_req_list,
-			struct cam_ctx_request, list);
-	} else if (!list_empty(&ctx->wait_req_list)) {
-		req = list_first_entry(&ctx->wait_req_list,
-			struct cam_ctx_request, list);
-	} else if (!list_empty(&ctx->pending_req_list)) {
-		req = list_first_entry(&ctx->pending_req_list,
-			struct cam_ctx_request, list);
-	} else {
-		CAM_ERR(CAM_CTXT, "[%s][%d] no request to dump",
-			ctx->dev_name, ctx->ctx_id);
-	}
-	spin_unlock_bh(&ctx->lock);
-
-	/* Check for min len in case of available request to dump */
-	if (req != NULL) {
-		remain_len = buf_len - dump_args->offset;
-		min_len = sizeof(struct cam_context_dump_header) +
-			(CAM_CTXT_DUMP_NUM_WORDS + req->num_in_map_entries +
-			(req->num_out_map_entries * 2)) * sizeof(uint64_t);
-
-		if (remain_len < min_len) {
-			CAM_WARN(CAM_CTXT, "dump buffer exhaust remain %zu min %u",
-				remain_len, min_len);
-			cam_mem_put_cpu_buf(dump_args->buf_handle);
-			return -ENOSPC;
-		}
+	/* Dump context info */
+	remain_len = buf_len - dump_args->offset;
+	if (remain_len < sizeof(struct cam_context_dump_header)) {
+		CAM_WARN(CAM_CTXT,
+			"No sufficient space in dump buffer for headers, remain buf size: %d, header size: %d",
+			remain_len, sizeof(struct cam_context_dump_header));
+		cam_mem_put_cpu_buf(dump_args->buf_handle);
+		return -ENOSPC;
 	}
 
-	/* Dump context info */
 	dst = (uint8_t *)cpu_addr + dump_args->offset;
 	hdr = (struct cam_context_dump_header *)dst;
 	local_len =
@@ -1611,6 +1588,15 @@ static int cam_context_user_dump(struct cam_context *ctx,
 	if (!list_empty(&ctx->wait_req_list)) {
 		list_for_each_entry_safe(req, req_temp, &ctx->wait_req_list, list) {
 			for (i = 0; i < req->num_out_map_entries; i++) {
+				remain_len = buf_len - dump_args->offset;
+				if (remain_len < sizeof(struct cam_context_dump_header)) {
+					CAM_WARN(CAM_CTXT,
+						"No sufficient space in dump buffer for headers, remain buf size: %d, header size: %d",
+						remain_len, sizeof(struct cam_context_dump_header));
+					cam_mem_put_cpu_buf(dump_args->buf_handle);
+					return -ENOSPC;
+				}
+
 				dst = (uint8_t *)cpu_addr + dump_args->offset;
 				hdr = (struct cam_context_dump_header *)dst;
 				local_len = dump_args->offset +
@@ -1643,6 +1629,15 @@ static int cam_context_user_dump(struct cam_context *ctx,
 	if (!list_empty(&ctx->pending_req_list)) {
 		list_for_each_entry_safe(req, req_temp, &ctx->pending_req_list, list) {
 			for (i = 0; i < req->num_out_map_entries; i++) {
+				remain_len = buf_len - dump_args->offset;
+				if (remain_len < sizeof(struct cam_context_dump_header)) {
+					CAM_WARN(CAM_CTXT,
+						"No sufficient space in dump buffer for headers, remain buf size: %d, header size: %d",
+						remain_len, sizeof(struct cam_context_dump_header));
+					cam_mem_put_cpu_buf(dump_args->buf_handle);
+					return -ENOSPC;
+				}
+
 				dst = (uint8_t *)cpu_addr + dump_args->offset;
 				hdr = (struct cam_context_dump_header *)dst;
 				local_len = dump_args->offset +
@@ -1675,6 +1670,15 @@ static int cam_context_user_dump(struct cam_context *ctx,
 	if (!list_empty(&ctx->active_req_list)) {
 		list_for_each_entry_safe(req, req_temp, &ctx->active_req_list, list) {
 			for (i = 0; i < req->num_out_map_entries; i++) {
+				remain_len = buf_len - dump_args->offset;
+				if (remain_len < sizeof(struct cam_context_dump_header)) {
+					CAM_WARN(CAM_CTXT,
+						"No sufficient space in dump buffer for headers, remain buf size: %d, header size: %d",
+						remain_len, sizeof(struct cam_context_dump_header));
+					cam_mem_put_cpu_buf(dump_args->buf_handle);
+					return -ENOSPC;
+				}
+
 				dst = (uint8_t *)cpu_addr + dump_args->offset;
 				hdr = (struct cam_context_dump_header *)dst;
 				local_len = dump_args->offset +