Blame SOURCES/0012-goodix-moc-Fix-several-places-where-the-plugin-code-.patch

9874f4
From e80f277f4c268d69c162123bc8cbb1819224cea2 Mon Sep 17 00:00:00 2001
9874f4
From: Richard Hughes <richard@hughsie.com>
9874f4
Date: Wed, 10 Feb 2021 13:22:59 +0000
9874f4
Subject: [PATCH 12/12] goodix-moc: Fix several places where the plugin code
9874f4
 might crash
9874f4
9874f4
Fixes https://github.com/fwupd/fwupd/issues/2850
9874f4
---
9874f4
 plugins/goodix-moc/fu-goodixmoc-common.c |  83 ----------------
9874f4
 plugins/goodix-moc/fu-goodixmoc-common.h |  19 +---
9874f4
 plugins/goodix-moc/fu-goodixmoc-device.c | 120 +++++++++++++----------
9874f4
 plugins/goodix-moc/meson.build           |   1 -
9874f4
 4 files changed, 72 insertions(+), 151 deletions(-)
9874f4
 delete mode 100644 plugins/goodix-moc/fu-goodixmoc-common.c
9874f4
9874f4
diff --git plugins/goodix-moc/fu-goodixmoc-common.c plugins/goodix-moc/fu-goodixmoc-common.c
9874f4
deleted file mode 100644
9874f4
index 7c81434d..00000000
9874f4
--- plugins/goodix-moc/fu-goodixmoc-common.c
9874f4
+++ /dev/null
9874f4
@@ -1,83 +0,0 @@
9874f4
-/*
9874f4
- * Copyright (C) 2016 Richard Hughes <richard@hughsie.com>
9874f4
- * Copyright (C) 2020 boger wang <boger@goodix.com>
9874f4
- *
9874f4
- * SPDX-License-Identifier: LGPL-2.1+
9874f4
- */
9874f4
-
9874f4
-#include "config.h"
9874f4
-
9874f4
-#include <fwupd.h>
9874f4
-#include <string.h>
9874f4
-
9874f4
-#include "fu-common.h"
9874f4
-#include "fu-goodixmoc-common.h"
9874f4
-
9874f4
-void
9874f4
-fu_goodixmoc_build_header (GxfpPkgHeader *pheader,
9874f4
-			   guint16	  len,
9874f4
-			   guint8	  cmd0,
9874f4
-			   guint8	  cmd1,
9874f4
-			   GxPkgType	  type)
9874f4
-{
9874f4
-	static guint8 dummy_seq = 0;
9874f4
-
9874f4
-	g_return_if_fail (pheader != NULL);
9874f4
-
9874f4
-	pheader->cmd0 = (cmd0);
9874f4
-	pheader->cmd1 = (cmd1);
9874f4
-	pheader->pkg_flag = (guint8)type;
9874f4
-	pheader->reserved = dummy_seq++;
9874f4
-	pheader->len = len + GX_SIZE_CRC32;
9874f4
-	pheader->crc8 = fu_common_crc8 ((guint8 *)pheader, 6);
9874f4
-	pheader->rev_crc8 = ~pheader->crc8;
9874f4
-}
9874f4
-
9874f4
-gboolean
9874f4
-fu_goodixmoc_parse_header (guint8 *buf, guint32 bufsz,
9874f4
-			   GxfpPkgHeader *pheader, GError **error)
9874f4
-{
9874f4
-	g_return_val_if_fail (buf != NULL, FALSE);
9874f4
-	g_return_val_if_fail (pheader != NULL, FALSE);
9874f4
-
9874f4
-	if (!fu_memcpy_safe ((guint8 *) &pheader, sizeof(*pheader), 0x0,	/* dst */
9874f4
-			     buf, bufsz, 0x01,					/* src */
9874f4
-			     sizeof(*pheader), error))
9874f4
-		return FALSE;
9874f4
-	memcpy (pheader, buf, sizeof(*pheader));
9874f4
-	pheader->len = GUINT16_FROM_LE(*(buf + 4));
9874f4
-	pheader->len -= GX_SIZE_CRC32;
9874f4
-	return TRUE;
9874f4
-}
9874f4
-
9874f4
-gboolean
9874f4
-fu_goodixmoc_parse_body (guint8 cmd, guint8 *buf, guint32 bufsz,
9874f4
-			 GxfpCmdResp *presp, GError **error)
9874f4
-{
9874f4
-	g_return_val_if_fail (buf != NULL, FALSE);
9874f4
-	g_return_val_if_fail (presp != NULL, FALSE);
9874f4
-
9874f4
-	presp->result = buf[0];
9874f4
-	switch (cmd) {
9874f4
-	case GX_CMD_ACK:
9874f4
-		if (bufsz == 0) {
9874f4
-			g_set_error_literal (error,
9874f4
-					     FWUPD_ERROR,
9874f4
-					     FWUPD_ERROR_INTERNAL,
9874f4
-					     "invalid bufsz");
9874f4
-			return FALSE;
9874f4
-		}
9874f4
-		presp->ack_msg.cmd = buf[1];
9874f4
-		break;
9874f4
-	case GX_CMD_VERSION:
9874f4
-		if (!fu_memcpy_safe ((guint8 *) &presp->version_info,
9874f4
-				     sizeof(presp->version_info), 0x0,		/* dst */
9874f4
-				     buf, bufsz, 0x01,				/* src */
9874f4
-				     sizeof(GxfpVersiomInfo), error))
9874f4
-			return FALSE;
9874f4
-		break;
9874f4
-	default:
9874f4
-		break;
9874f4
-	}
9874f4
-	return TRUE;
9874f4
-}
9874f4
diff --git plugins/goodix-moc/fu-goodixmoc-common.h plugins/goodix-moc/fu-goodixmoc-common.h
9874f4
index 4bbdc0c8..c4b69954 100644
9874f4
--- plugins/goodix-moc/fu-goodixmoc-common.h
9874f4
+++ plugins/goodix-moc/fu-goodixmoc-common.h
9874f4
@@ -35,7 +35,7 @@ typedef struct {
9874f4
 	guint8		 protocol[8];
9874f4
 	guint8		 flashVersion[8];
9874f4
 	guint8		 reserved[62];
9874f4
-} GxfpVersiomInfo;
9874f4
+} GxfpVersionInfo;
9874f4
 
9874f4
 typedef struct {
9874f4
 	guint8		 cmd;
9874f4
@@ -46,7 +46,7 @@ typedef struct {
9874f4
 	guint8		 result;
9874f4
 	union {
9874f4
 		GxfpAckMsg	ack_msg;
9874f4
-		GxfpVersiomInfo version_info;
9874f4
+		GxfpVersionInfo version_info;
9874f4
 	};
9874f4
 } GxfpCmdResp;
9874f4
 
9874f4
@@ -64,18 +64,3 @@ typedef struct __attribute__((__packed__)) {
9874f4
 	guint8		 crc8;
9874f4
 	guint8		 rev_crc8;
9874f4
 } GxfpPkgHeader;
9874f4
-
9874f4
-void		 fu_goodixmoc_build_header	(GxfpPkgHeader	*pheader,
9874f4
-						 guint16	 len,
9874f4
-						 guint8		 cmd0,
9874f4
-						 guint8		 cmd1,
9874f4
-						 GxPkgType	 type);
9874f4
-gboolean	 fu_goodixmoc_parse_header	(guint8		*buf,
9874f4
-						 guint32	 bufsz,
9874f4
-						 GxfpPkgHeader	*pheader,
9874f4
-						 GError		**error);
9874f4
-gboolean	 fu_goodixmoc_parse_body	(guint8		 cmd,
9874f4
-						 guint8		*buf,
9874f4
-						 guint32	 bufsz,
9874f4
-						 GxfpCmdResp	*presp,
9874f4
-						 GError		**error);
9874f4
diff --git plugins/goodix-moc/fu-goodixmoc-device.c plugins/goodix-moc/fu-goodixmoc-device.c
9874f4
index f216aec7..3d359dab 100644
9874f4
--- plugins/goodix-moc/fu-goodixmoc-device.c
9874f4
+++ plugins/goodix-moc/fu-goodixmoc-device.c
9874f4
@@ -14,6 +14,7 @@
9874f4
 
9874f4
 struct _FuGoodixMocDevice {
9874f4
 	FuUsbDevice	parent_instance;
9874f4
+	guint8		dummy_seq;
9874f4
 };
9874f4
 
9874f4
 G_DEFINE_TYPE (FuGoodixMocDevice, fu_goodixmoc_device, FU_TYPE_USB_DEVICE)
9874f4
@@ -27,26 +28,34 @@ G_DEFINE_TYPE (FuGoodixMocDevice, fu_goodixmoc_device, FU_TYPE_USB_DEVICE)
9874f4
 #define GX_FLASH_TRANSFER_BLOCK_SIZE	1000	/* 1000 */
9874f4
 
9874f4
 static gboolean
9874f4
-goodixmoc_device_cmd_send (GUsbDevice *usbdevice,
9874f4
+goodixmoc_device_cmd_send (FuGoodixMocDevice *self,
9874f4
 			   guint8      cmd0,
9874f4
 			   guint8      cmd1,
9874f4
 			   GxPkgType   type,
9874f4
 			   GByteArray *req,
9874f4
 			   GError    **error)
9874f4
 {
9874f4
-	GxfpPkgHeader header = { 0 };
9874f4
-	guint32 crc_actual = 0;
9874f4
+	GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (self));
9874f4
+	guint32 crc_all = 0;
9874f4
+	guint32 crc_hdr = 0;
9874f4
 	gsize actual_len = 0;
9874f4
 	g_autoptr(GByteArray) buf = g_byte_array_new ();
9874f4
 
9874f4
-	fu_goodixmoc_build_header (&header, req->len, cmd0, cmd1, type);
9874f4
-	g_byte_array_append (buf, (guint8 *)&header, sizeof(header));
9874f4
+	/* build header */
9874f4
+	fu_byte_array_append_uint8 (buf, cmd0);
9874f4
+	fu_byte_array_append_uint8 (buf, cmd1);
9874f4
+	fu_byte_array_append_uint8 (buf, type);			/* pkg_flag */
9874f4
+	fu_byte_array_append_uint8 (buf, self->dummy_seq++);	/* reserved */
9874f4
+	fu_byte_array_append_uint16 (buf, req->len + GX_SIZE_CRC32, G_LITTLE_ENDIAN);
9874f4
+	crc_hdr = fu_common_crc8 (buf->data, buf->len);
9874f4
+	fu_byte_array_append_uint8 (buf, crc_hdr);
9874f4
+	fu_byte_array_append_uint8 (buf, ~crc_hdr);
9874f4
 	g_byte_array_append (buf, req->data, req->len);
9874f4
-	crc_actual = fu_common_crc32 (buf->data, sizeof(header) + req->len);
9874f4
-	fu_byte_array_append_uint32 (buf, crc_actual, G_LITTLE_ENDIAN);
9874f4
+	crc_all = fu_common_crc32 (buf->data, buf->len);
9874f4
+	fu_byte_array_append_uint32 (buf, crc_all, G_LITTLE_ENDIAN);
9874f4
 
9874f4
 	/* send zero length package */
9874f4
-	if (!g_usb_device_bulk_transfer (usbdevice,
9874f4
+	if (!g_usb_device_bulk_transfer (usb_device,
9874f4
 					 GX_USB_BULK_EP_OUT,
9874f4
 					 NULL,
9874f4
 					 0,
9874f4
@@ -62,7 +71,7 @@ goodixmoc_device_cmd_send (GUsbDevice *usbdevice,
9874f4
 	}
9874f4
 
9874f4
 	/* send data */
9874f4
-	if (!g_usb_device_bulk_transfer (usbdevice,
9874f4
+	if (!g_usb_device_bulk_transfer (usb_device,
9874f4
 					 GX_USB_BULK_EP_OUT,
9874f4
 					 buf->data,
9874f4
 					 buf->len,
9874f4
@@ -84,12 +93,12 @@ goodixmoc_device_cmd_send (GUsbDevice *usbdevice,
9874f4
 }
9874f4
 
9874f4
 static gboolean
9874f4
-goodixmoc_device_cmd_recv (GUsbDevice  *usbdevice,
9874f4
+goodixmoc_device_cmd_recv (FuGoodixMocDevice *self,
9874f4
 			   GxfpCmdResp *presponse,
9874f4
 			   gboolean     data_reply,
9874f4
 			   GError     **error)
9874f4
 {
9874f4
-	GxfpPkgHeader header = { 0 };
9874f4
+	GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (self));
9874f4
 	guint32 crc_actual = 0;
9874f4
 	guint32 crc_calculated = 0;
9874f4
 	gsize actual_len = 0;
9874f4
@@ -102,9 +111,11 @@ goodixmoc_device_cmd_recv (GUsbDevice  *usbdevice,
9874f4
 	* | zlp | ack | zlp | data |
9874f4
 	*/
9874f4
 	while (1) {
9874f4
+		guint16 header_len = 0x0;
9874f4
+		guint8 header_cmd0 = 0x0;
9874f4
 		g_autoptr(GByteArray) reply = g_byte_array_new ();
9874f4
 		fu_byte_array_set_size (reply, GX_FLASH_TRANSFER_BLOCK_SIZE);
9874f4
-		if (!g_usb_device_bulk_transfer (usbdevice,
9874f4
+		if (!g_usb_device_bulk_transfer (usb_device,
9874f4
 						 GX_USB_BULK_EP_IN,
9874f4
 						 reply->data,
9874f4
 						 reply->len,
9874f4
@@ -125,12 +136,14 @@ goodixmoc_device_cmd_recv (GUsbDevice  *usbdevice,
9874f4
 		}
9874f4
 
9874f4
 		/* parse package header */
9874f4
-		if (!fu_goodixmoc_parse_header (reply->data,
9874f4
-						actual_len,
9874f4
-						&header,
9874f4
-						error))
9874f4
+		if (!fu_common_read_uint8_safe (reply->data, reply->len, 0x0,
9874f4
+						&header_cmd0, error))
9874f4
+			return FALSE;
9874f4
+		if (!fu_common_read_uint16_safe	(reply->data, reply->len, 0x4,
9874f4
+						 &header_len, G_LITTLE_ENDIAN,
9874f4
+						 error))
9874f4
 			return FALSE;
9874f4
-		offset = sizeof(header) + header.len;
9874f4
+		offset = sizeof(GxfpPkgHeader) + header_len - GX_SIZE_CRC32;
9874f4
 		crc_actual = fu_common_crc32 (reply->data, offset);
9874f4
 		if (!fu_common_read_uint32_safe	(reply->data,
9874f4
 						 reply->len,
9874f4
@@ -149,15 +162,33 @@ goodixmoc_device_cmd_recv (GUsbDevice  *usbdevice,
9874f4
 		}
9874f4
 
9874f4
 		/* parse package data */
9874f4
-		if (!fu_goodixmoc_parse_body (header.cmd0,
9874f4
-					      reply->data + sizeof(header),
9874f4
-					      header.len,
9874f4
-					      presponse,
9874f4
-					      error))
9874f4
+		if (!fu_common_read_uint8_safe (reply->data, reply->len,
9874f4
+						sizeof(GxfpPkgHeader) + 0x00,
9874f4
+						&presponse->result, error))
9874f4
 			return FALSE;
9874f4
+		if (header_cmd0 == GX_CMD_ACK) {
9874f4
+			if (header_len == 0) {
9874f4
+				g_set_error_literal (error,
9874f4
+						     FWUPD_ERROR,
9874f4
+						     FWUPD_ERROR_INTERNAL,
9874f4
+						     "invalid bufsz");
9874f4
+				return FALSE;
9874f4
+			}
9874f4
+			if (!fu_common_read_uint8_safe (reply->data, reply->len,
9874f4
+							sizeof(GxfpPkgHeader) + 0x01,
9874f4
+							&presponse->ack_msg.cmd, error))
9874f4
+				return FALSE;
9874f4
+		} else if (header_cmd0 == GX_CMD_VERSION) {
9874f4
+			if (!fu_memcpy_safe ((guint8 *) &presponse->version_info,
9874f4
+					     sizeof(presponse->version_info), 0x0,	/* dst */
9874f4
+					     reply->data, reply->len,
9874f4
+					     sizeof(GxfpPkgHeader) + 0x01,		/* src */
9874f4
+					     sizeof(GxfpVersionInfo), error))
9874f4
+				return FALSE;
9874f4
+		}
9874f4
 
9874f4
 		/* continue after ack received */
9874f4
-		if (header.cmd0 == GX_CMD_ACK && data_reply)
9874f4
+		if (header_cmd0 == GX_CMD_ACK && data_reply)
9874f4
 			continue;
9874f4
 		break;
9874f4
 	}
9874f4
@@ -176,36 +207,27 @@ fu_goodixmoc_device_cmd_xfer (FuGoodixMocDevice	*device,
9874f4
 			      gboolean		 data_reply,
9874f4
 			      GError		**error)
9874f4
 {
9874f4
-	GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE(device));
9874f4
-	if (!goodixmoc_device_cmd_send (usb_device, cmd0, cmd1, type, req, error))
9874f4
+	FuGoodixMocDevice *self = FU_GOODIXMOC_DEVICE(device);
9874f4
+	if (!goodixmoc_device_cmd_send (self, cmd0, cmd1, type, req, error))
9874f4
 		return FALSE;
9874f4
-	return goodixmoc_device_cmd_recv (usb_device, presponse, data_reply, error);
9874f4
+	return goodixmoc_device_cmd_recv (self, presponse, data_reply, error);
9874f4
 }
9874f4
 
9874f4
-static gchar *
9874f4
-fu_goodixmoc_device_get_version (FuGoodixMocDevice *self, GError **error)
9874f4
+static gboolean
9874f4
+fu_goodixmoc_device_setup_version (FuGoodixMocDevice *self, GError **error)
9874f4
 {
9874f4
 	GxfpCmdResp rsp = { 0 };
9874f4
-	gchar ver[9] = { 0 };
9874f4
-	guint8 dummy = 0;
9874f4
+	g_autofree gchar *version = NULL;
9874f4
 	g_autoptr(GByteArray) req = g_byte_array_new ();
9874f4
 
9874f4
-	fu_byte_array_append_uint8 (req, dummy);
9874f4
+	fu_byte_array_append_uint8 (req, 0);	/* dummy */
9874f4
 	if (!fu_goodixmoc_device_cmd_xfer (self, GX_CMD_VERSION, GX_CMD1_DEFAULT,
9874f4
-					  GX_PKG_TYPE_EOP,
9874f4
-					  req,
9874f4
-					  &rsp,
9874f4
-					  TRUE,
9874f4
-					  error))
9874f4
-		return NULL;
9874f4
-	if (!fu_memcpy_safe ((guint8 *) ver, sizeof(ver), 0x0,
9874f4
-			      rsp.version_info.fwversion,
9874f4
-			      sizeof(rsp.version_info.fwversion),
9874f4
-			      0x0,
9874f4
-			      sizeof(rsp.version_info.fwversion),
9874f4
-			      error))
9874f4
-		return NULL;
9874f4
-	return g_strndup (ver, sizeof(ver));
9874f4
+					  GX_PKG_TYPE_EOP, req, &rsp, TRUE, error))
9874f4
+		return FALSE;
9874f4
+	version = g_strndup ((const gchar *) rsp.version_info.fwversion,
9874f4
+			     sizeof(rsp.version_info.fwversion));
9874f4
+	fu_device_set_version (FU_DEVICE (self), version);
9874f4
+	return TRUE;
9874f4
 }
9874f4
 
9874f4
 static gboolean
9874f4
@@ -281,15 +303,13 @@ fu_goodixmoc_device_open (FuUsbDevice *device, GError **error)
9874f4
 static gboolean
9874f4
 fu_goodixmoc_device_setup (FuDevice *device, GError **error)
9874f4
 {
9874f4
-	FuGoodixMocDevice *self = FU_GOODIXMOC_DEVICE(device);
9874f4
-	g_autofree gchar *version = NULL;
9874f4
+	FuGoodixMocDevice *self = FU_GOODIXMOC_DEVICE (device);
9874f4
 
9874f4
-	version = fu_goodixmoc_device_get_version (self, error);
9874f4
-	if (version == NULL) {
9874f4
+	/* ensure version */
9874f4
+	if (!fu_goodixmoc_device_setup_version (self, error)) {
9874f4
 		g_prefix_error (error, "failed to get firmware version: ");
9874f4
 		return FALSE;
9874f4
 	}
9874f4
-	fu_device_set_version (device, version);
9874f4
 
9874f4
 	/* success */
9874f4
 	return TRUE;
9874f4
diff --git plugins/goodix-moc/meson.build plugins/goodix-moc/meson.build
9874f4
index 4e1287e4..178b35d8 100644
9874f4
--- plugins/goodix-moc/meson.build
9874f4
+++ plugins/goodix-moc/meson.build
9874f4
@@ -9,7 +9,6 @@ install_data([
9874f4
 shared_module('fu_plugin_goodixmoc',
9874f4
   fu_hash,
9874f4
   sources : [
9874f4
-    'fu-goodixmoc-common.c',
9874f4
     'fu-goodixmoc-device.c',
9874f4
     'fu-plugin-goodixmoc.c',
9874f4
   ],
9874f4
-- 
9874f4
2.29.2
9874f4