lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20241128-venus_oob_2-v2-2-483ae0a464b8@quicinc.com>
Date: Thu, 28 Nov 2024 10:35:12 +0530
From: Vikash Garodia <quic_vgarodia@...cinc.com>
To: Stanimir Varbanov <stanimir.k.varbanov@...il.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@...aro.org>,
        Mauro Carvalho Chehab <mchehab@...nel.org>,
        Tomasz Figa <tfiga@...omium.org>,
        Hans Verkuil <hans.verkuil@...co.com>
CC: Stanimir Varbanov <stanimir.varbanov@...aro.org>,
        Mauro Carvalho Chehab
	<mchehab+samsung@...nel.org>,
        Dmitry Baryshkov <dmitry.baryshkov@...aro.org>,
        <linux-media@...r.kernel.org>, <linux-arm-msm@...r.kernel.org>,
        <linux-kernel@...r.kernel.org>,
        Vikash Garodia <quic_vgarodia@...cinc.com>, <stable@...r.kernel.org>
Subject: [PATCH v2 2/4] media: venus: hfi_parser: avoid OOB access beyond
 payload word count

words_count denotes the number of words in total payload, while data
points to payload of various property within it. When words_count
reaches last word, data can access memory beyond the total payload. This
can lead to OOB access. Refactor the parsing logic such that the
remaining payload is checked before parsing it.

Cc: stable@...r.kernel.org
Fixes: 1a73374a04e5 ("media: venus: hfi_parser: add common capability parser")
Signed-off-by: Vikash Garodia <quic_vgarodia@...cinc.com>
---
 drivers/media/platform/qcom/venus/hfi_parser.c | 57 +++++++++++++++++++++-----
 1 file changed, 46 insertions(+), 11 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c
index 1cc17f3dc8948160ea6c3015d2c03e475b8aa29e..14349c2f84b205a8b79dee3acff1408bb63ac54a 100644
--- a/drivers/media/platform/qcom/venus/hfi_parser.c
+++ b/drivers/media/platform/qcom/venus/hfi_parser.c
@@ -282,8 +282,8 @@ static int hfi_platform_parser(struct venus_core *core, struct venus_inst *inst)
 u32 hfi_parser(struct venus_core *core, struct venus_inst *inst, void *buf,
 	       u32 size)
 {
+	u32 *words = buf, *payload, codecs = 0, domain = 0;
 	unsigned int words_count = size >> 2;
-	u32 *word = buf, *data, codecs = 0, domain = 0;
 	int ret;
 
 	ret = hfi_platform_parser(core, inst);
@@ -301,36 +301,71 @@ u32 hfi_parser(struct venus_core *core, struct venus_inst *inst, void *buf,
 	}
 
 	while (words_count) {
-		data = word + 1;
+		payload = words + 1;
 
-		switch (*word) {
+		switch (*words) {
 		case HFI_PROPERTY_PARAM_CODEC_SUPPORTED:
-			parse_codecs(core, data);
+			if (words_count < sizeof(struct hfi_codec_supported))
+				return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+			parse_codecs(core, payload);
 			init_codecs(core);
+			words_count -= sizeof(struct hfi_codec_supported);
+			words += sizeof(struct hfi_codec_supported);
 			break;
 		case HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED:
-			parse_max_sessions(core, data);
+			if (words_count < sizeof(struct hfi_max_sessions_supported))
+				return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+			parse_max_sessions(core, payload);
+			words_count -= sizeof(struct hfi_max_sessions_supported);
+			words += sizeof(struct hfi_max_sessions_supported);
 			break;
 		case HFI_PROPERTY_PARAM_CODEC_MASK_SUPPORTED:
-			parse_codecs_mask(&codecs, &domain, data);
+			if (words_count < sizeof(struct hfi_codec_mask_supported))
+				return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+			parse_codecs_mask(&codecs, &domain, payload);
+			words_count -= sizeof(struct hfi_codec_mask_supported);
+			words += sizeof(struct hfi_codec_mask_supported);
 			break;
 		case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED:
-			parse_raw_formats(core, codecs, domain, data);
+			if (words_count < sizeof(struct hfi_uncompressed_format_supported))
+				return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+			parse_raw_formats(core, codecs, domain, payload);
+			words_count -= sizeof(struct hfi_uncompressed_format_supported);
+			words += sizeof(struct hfi_uncompressed_format_supported);
 			break;
 		case HFI_PROPERTY_PARAM_CAPABILITY_SUPPORTED:
-			parse_caps(core, codecs, domain, data);
+			if (words_count < sizeof(struct hfi_capabilities))
+				return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+			parse_caps(core, codecs, domain, payload);
+			words_count -= sizeof(struct hfi_capabilities);
+			words += sizeof(struct hfi_capabilities);
 			break;
 		case HFI_PROPERTY_PARAM_PROFILE_LEVEL_SUPPORTED:
-			parse_profile_level(core, codecs, domain, data);
+			if (words_count < sizeof(struct hfi_profile_level_supported))
+				return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+			parse_profile_level(core, codecs, domain, payload);
+			words_count -= sizeof(struct hfi_profile_level_supported);
+			words += sizeof(struct hfi_profile_level_supported);
 			break;
 		case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE_SUPPORTED:
-			parse_alloc_mode(core, codecs, domain, data);
+			if (words_count < sizeof(struct hfi_buffer_alloc_mode_supported))
+				return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+			parse_alloc_mode(core, codecs, domain, payload);
+			words_count -= sizeof(struct hfi_buffer_alloc_mode_supported);
+			words += sizeof(struct hfi_buffer_alloc_mode_supported);
 			break;
 		default:
 			break;
 		}
 
-		word++;
+		words++;
 		words_count--;
 	}
 

-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ