diff options
author | Yu Wu <quic_zwy@quicinc.com> | 2022-08-30 16:34:57 +0800 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2022-11-16 23:34:14 -0800 |
commit | dceb5b3d372b8cfd2605aaa0bc09ee23eb52ba8f (patch) | |
tree | 534a844787d6a2f44bba5f51e7c57efb15064fdd | |
parent | 02615067111e81ff6543434f66740771f5a0c271 (diff) | |
download | touch-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.c | 32 |
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; |