drivers: soc: add size check
Add size check to ensure the payload fits inside the declared payload
size to prevent loss of data when copying.
References: CVE-2017-0451
CRs-Fixed: 2009224
Signed-off-by: Siena Richard <sienar@codeaurora.org>
Change-Id: I4275c626605272941143b54a7b8861b25f8e750a
diff --git a/drivers/soc/qcom/qdsp6v2/voice_svc.c b/drivers/soc/qcom/qdsp6v2/voice_svc.c
index 85359d6..5d70c16 100644
--- a/drivers/soc/qcom/qdsp6v2/voice_svc.c
+++ b/drivers/soc/qcom/qdsp6v2/voice_svc.c
@@ -361,6 +361,9 @@
struct voice_svc_prvt *prtd;
struct voice_svc_write_msg *data = NULL;
uint32_t cmd;
+ struct voice_svc_register *register_data = NULL;
+ struct voice_svc_cmd_request *request_data = NULL;
+ uint32_t request_payload_size;
pr_debug("%s\n", __func__);
@@ -409,12 +412,19 @@
*/
if (count == (sizeof(struct voice_svc_write_msg) +
sizeof(struct voice_svc_register))) {
- ret = process_reg_cmd(
- (struct voice_svc_register *)data->payload, prtd);
+ register_data =
+ (struct voice_svc_register *)data->payload;
+ if (register_data == NULL) {
+ pr_err("%s: register data is NULL", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ ret = process_reg_cmd(register_data, prtd);
if (!ret)
ret = count;
} else {
- pr_err("%s: invalid payload size\n", __func__);
+ pr_err("%s: invalid data payload size for register command\n",
+ __func__);
ret = -EINVAL;
goto done;
}
@@ -423,16 +433,37 @@
/*
* Check that count reflects the expected size to ensure
* sufficient memory was allocated. Since voice_svc_cmd_request
- * has a variable size, check the minimum value count must be.
+ * has a variable size, check the minimum value count must be to
+ * parse the message request then check the minimum size to hold
+ * the payload of the message request.
*/
if (count >= (sizeof(struct voice_svc_write_msg) +
sizeof(struct voice_svc_cmd_request))) {
- ret = voice_svc_send_req(
- (struct voice_svc_cmd_request *)data->payload, prtd);
- if (!ret)
- ret = count;
+ request_data =
+ (struct voice_svc_cmd_request *)data->payload;
+ if (request_data == NULL) {
+ pr_err("%s: request data is NULL", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ request_payload_size = request_data->payload_size;
+
+ if (count >= (sizeof(struct voice_svc_write_msg) +
+ sizeof(struct voice_svc_cmd_request) +
+ request_payload_size)) {
+ ret = voice_svc_send_req(request_data, prtd);
+ if (!ret)
+ ret = count;
+ } else {
+ pr_err("%s: invalid request payload size\n",
+ __func__);
+ ret = -EINVAL;
+ goto done;
+ }
} else {
- pr_err("%s: invalid payload size\n", __func__);
+ pr_err("%s: invalid data payload size for request command\n",
+ __func__);
ret = -EINVAL;
goto done;
}