summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Wu <quic_zwy@quicinc.com>2022-08-30 16:34:57 +0800
committerGerrit - the friendly Code Review server <code-review@localhost>2022-11-16 23:34:14 -0800
commitdceb5b3d372b8cfd2605aaa0bc09ee23eb52ba8f (patch)
tree534a844787d6a2f44bba5f51e7c57efb15064fdd
parent02615067111e81ff6543434f66740771f5a0c271 (diff)
downloadtouch-dceb5b3d372b8cfd2605aaa0bc09ee23eb52ba8f.tar.gz
touch: goodix: Add parameter check to avoid security issue
In brl_read_config function, it is possible the parameter size is smaller than cfg_head, and if in some case the cfg is corrupted, the code will possible reach memcpy function, in this funcion, we might be writing to a place where cannot even hold 64 bytes. That will cause security issue. Change-Id: I6ac69de62e8565dc4bee4befbe3124c60118f3a1 Signed-off-by: Yu Wu <quic_zwy@quicinc.com>
-rw-r--r--goodix_berlin_driver/goodix_brl_hw.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/goodix_berlin_driver/goodix_brl_hw.c b/goodix_berlin_driver/goodix_brl_hw.c
index f7b2afd..b14c288 100644
--- a/goodix_berlin_driver/goodix_brl_hw.c
+++ b/goodix_berlin_driver/goodix_brl_hw.c
@@ -497,9 +497,16 @@ static int brl_send_config(struct goodix_ts_core *cd, u8 *cfg, int len)
{
int ret;
u8 *tmp_buf;
+ u16 cfg_head_len = sizeof(struct goodix_config_head)/sizeof(u8);
struct goodix_ts_cmd cfg_cmd;
struct goodix_ic_info_misc *misc = &cd->ic_info.misc;
struct goodix_ts_hw_ops *hw_ops = cd->hw_ops;
+ struct goodix_config_head *cfg_head = (struct goodix_config_head *)cfg;
+
+ if (!cd || !cfg) {
+ ts_err("input parameter is NULL");
+ return -EINVAL;
+ }
if (len > misc->fw_buffer_max_len) {
ts_err("config len exceed limit %d > %d",
@@ -507,6 +514,29 @@ static int brl_send_config(struct goodix_ts_core *cd, u8 *cfg, int len)
return -EINVAL;
}
+ if (len < cfg_head_len) {
+ ts_err("config buffer size %d smaller than header size %d",
+ len, sizeof(*cfg_head));
+ return -EINVAL;
+ }
+
+ if (len != cfg_head_len + cfg_head->cfg_len) {
+ ts_err("config buffer size %d not equal to head %d + cfg_len %d",
+ len, cfg_head_len, cfg_head->cfg_len);
+ return -EINVAL;
+ }
+
+ if (checksum_cmp(cfg, cfg_head_len, CHECKSUM_MODE_U8_LE)) {
+ ts_err("config head checksum error");
+ return -EINVAL;
+
+ }
+
+ if (checksum_cmp(cfg + cfg_head_len, cfg_head->cfg_len, CHECKSUM_MODE_U16_LE)) {
+ ts_err("config body checksum error");
+ return -EINVAL;
+ }
+
tmp_buf = kzalloc(len, GFP_KERNEL);
if (!tmp_buf)
return -ENOMEM;
@@ -573,7 +603,7 @@ static int brl_read_config(struct goodix_ts_core *cd, u8 *cfg, int size)
struct goodix_ts_hw_ops *hw_ops = cd->hw_ops;
struct goodix_config_head cfg_head;
- if (!cfg)
+ if (!cfg || sizeof(cfg_head) > size)
return -EINVAL;
cfg_cmd.len = CONFIG_CND_LEN;