lsm: check payload size validity before using it as array index
Payload size validity is not checked before using it in array index.
Check payload size to avoid out-of-boundary memory.
Change-Id: Ic0b06bb331fc1753ff7543bb218ab12d6a4a3ca8
Signed-off-by: Kunlei Zhang <kunleiz@codeaurora.org>
diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c
index a702661..7511c46 100644
--- a/dsp/q6lsm.c
+++ b/dsp/q6lsm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, 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
@@ -195,7 +195,8 @@
struct lsm_cmd_read_done read_done;
token = data->token;
- if (data->payload_size > sizeof(read_done)) {
+ if (data->payload_size > sizeof(read_done) ||
+ data->payload_size < 6 * sizeof(payload[0])) {
pr_err("%s: read done error payload size %d expected size %zd\n",
__func__, data->payload_size,
sizeof(read_done));
@@ -213,6 +214,7 @@
if (client->cb)
client->cb(data->opcode, data->token,
(void *)&read_done,
+ sizeof(read_done),
client->priv);
return 0;
} else if (data->opcode == APR_BASIC_RSP_RESULT) {
@@ -238,6 +240,11 @@
__func__, token, client->session);
return -EINVAL;
}
+ if (data->payload_size < 2 * sizeof(payload[0])) {
+ pr_err("%s: payload has invalid size[%d]\n",
+ __func__, data->payload_size);
+ return -EINVAL;
+ }
client->cmd_err_code = payload[1];
if (client->cmd_err_code)
pr_err("%s: cmd 0x%x failed status %d\n",
@@ -258,7 +265,7 @@
if (client->cb)
client->cb(data->opcode, data->token, data->payload,
- client->priv);
+ data->payload_size, client->priv);
return 0;
}
@@ -1492,6 +1499,8 @@
"proc 0x%x SID 0x%x\n", __func__, data->opcode,
data->reset_event, data->reset_proc, sid);
+ if (sid < LSM_MIN_SESSION_ID || sid > LSM_MAX_SESSION_ID)
+ pr_err("%s: Invalid session %d\n", __func__, sid);
apr_reset(lsm_common.apr);
lsm_common.apr = NULL;
atomic_set(&lsm_common.apr_users, 0);
@@ -1557,7 +1566,8 @@
}
if (client->cb)
client->cb(data->opcode, data->token,
- data->payload, client->priv);
+ data->payload, data->payload_size,
+ client->priv);
return 0;
}