Browse Source

Merge "touch: goodix: Add more checks for brl_send_config function"

qctecmdr 2 years ago
parent
commit
20663c4ba9
2 changed files with 23 additions and 3 deletions
  1. 21 2
      goodix_berlin_driver/goodix_brl_hw.c
  2. 2 1
      goodix_berlin_driver/goodix_ts_utils.c

+ 21 - 2
goodix_berlin_driver/goodix_brl_hw.c

@@ -497,14 +497,33 @@ 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 (len > misc->fw_buffer_max_len) {
+	if (!cd || !cfg) {
+		ts_err("input parameter is NULL");
+		return -EINVAL;
+	} else if (len > misc->fw_buffer_max_len) {
 		ts_err("config len exceed limit %d > %d",
 			len, misc->fw_buffer_max_len);
 		return -EINVAL;
+	} else if (len < cfg_head_len) {
+		ts_err("config buffer size %d smaller than header size %d",
+			len, cfg_head_len);
+		return -EINVAL;
+	} else 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;
+	} else if (checksum_cmp(cfg, cfg_head_len, CHECKSUM_MODE_U8_LE)) {
+		ts_err("config head checksum error");
+		return -EINVAL;
+	} else 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);
@@ -573,7 +592,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;

+ 2 - 1
goodix_berlin_driver/goodix_ts_utils.c

@@ -71,7 +71,8 @@ int checksum_cmp(const u8 *data, int size, int mode)
 	u32 i;
 
 	if (((mode == CHECKSUM_MODE_U8_LE) && (size < 2)) ||
-		((mode == CHECKSUM_MODE_U16_LE) && (size < 4)))
+	    ((mode == CHECKSUM_MODE_U16_LE) && (size < 4)) ||
+	    ((mode == CHECKSUM_MODE_U16_LE) && (size % 2 != 0)))
 		return 1;
 
 	if (mode == CHECKSUM_MODE_U8_LE) {