goodixmoc/proto: Use FpiByteReader to parse the body

We had some read issues, so let's just use the safer reader that
makes things cleaner too

../libfprint/drivers/goodixmoc/goodix_proto.c:418:42: runtime error:
load of misaligned address 0x0000115ced29 for type 'uint16_t', which
requires 2 byte alignment
0x0000115ced29: note: pointer points here
 00 c0 3f  00 21 64 1c 00 00 00 00  64 00 43 01 01 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00
              ^
    #0 0x7f974ff9e868 in gx_proto_parse_body ../libfprint/drivers/goodixmoc/goodix_proto.c:418
    #1 0x7f974ff8ec79 in fp_cmd_receive_cb ../libfprint/drivers/goodixmoc/goodix.c:185
    #2 0x7f975003ca0c in transfer_finish_cb ../libfprint/fpi-usb-transfer.c:352
    #3 0x7f9756e57862 in g_task_return_now ../../glib/gio/gtask.c:1363
    #4 0x7f9756e5789c in complete_in_idle_cb ../../glib/gio/gtask.c:1377
    #5 0x7f97577f070b in g_main_dispatch ../../glib/glib/gmain.c:3373
    #6 0x7f97577f28de in g_main_context_dispatch_unlocked ../../glib/glib/gmain.c:4224
    #7 0x7f97577f28de in g_main_context_iterate_unlocked ../../glib/glib/gmain.c:4289
    #8 0x7f97577f2fef in g_main_context_iteration ../../glib/glib/gmain.c:4354
    #9 0x7f974fed4656 in fp_device_verify_sync ../libfprint/fp-device.c:1976
This commit is contained in:
Marco Trevisan (Treviño)
2025-02-13 19:10:01 +01:00
committed by Marco Trevisan
parent c7059dc61c
commit d8e0791554
3 changed files with 112 additions and 88 deletions

View File

@@ -22,7 +22,6 @@
#define FP_COMPONENT "goodixmoc"
#include "drivers_api.h"
#include "fpi-byte-reader.h"
#include "goodix_proto.h"
#include "goodix.h"
@@ -188,8 +187,11 @@ fp_cmd_receive_cb (FpiUsbTransfer *transfer,
cmd = MAKE_CMD_EX (header.cmd0, header.cmd1);
ret = gx_proto_parse_body (cmd, &transfer->buffer[PACKAGE_HEADER_SIZE], header.len, &cmd_reponse);
if (ret != 0)
fpi_byte_reader_set_pos (&reader, 0);
reader.data = &transfer->buffer[PACKAGE_HEADER_SIZE];
reader.size = header.len;
if (gx_proto_parse_body (cmd, &reader, &cmd_reponse) != 0)
{
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,

View File

@@ -18,6 +18,8 @@
*/
#include <glib.h>
#include <stdint.h>
#include "goodix_proto.h"
/*
@@ -243,13 +245,11 @@ gx_proto_parse_header (
}
static int
gx_proto_parse_fingerid (
uint8_t * fid_buffer,
uint16_t fid_buffer_size,
ptemplate_format_t template
)
gx_proto_parse_fingerid (const uint8_t * fid_buffer,
uint16_t fid_buffer_size,
ptemplate_format_t template)
{
uint8_t * buffer = NULL;
const uint8_t * buffer = NULL;
uint16_t Offset = 0;
if (!template || !fid_buffer)
@@ -283,35 +283,32 @@ gx_proto_parse_fingerid (
}
int
gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint16_t buffer_len, pgxfp_cmd_response_t presp)
gx_proto_parse_body (uint16_t cmd, FpiByteReader *byte_reader, pgxfp_cmd_response_t presp)
{
uint16_t offset = 0;
uint8_t *fingerlist = NULL;
if (!presp)
return -1;
if (!fpi_byte_reader_get_uint8 (byte_reader, &presp->result))
g_return_val_if_reached (-1);
if (!buffer || !presp)
return -1;
if (buffer_len < 1)
return -1;
presp->result = buffer[0];
switch (HIBYTE (cmd))
{
case RESPONSE_PACKAGE_CMD:
{
if (buffer_len < sizeof (gxfp_parse_msg_t) + 1)
return -1;
presp->parse_msg.ack_cmd = buffer[1];
if (!fpi_byte_reader_get_uint8 (byte_reader, &presp->parse_msg.ack_cmd))
g_return_val_if_reached (-1);
}
break;
case MOC_CMD0_UPDATE_CONFIG:
{
presp->finger_config.status = buffer[0];
if (buffer_len >= 3)
presp->finger_config.max_stored_prints = buffer[2];
else
/* to compatiable old version firmware */
presp->finger_config.max_stored_prints = FP_MAX_FINGERNUM;
presp->finger_config.status = presp->result;
/* to compatiable old version firmware */
presp->finger_config.max_stored_prints = FP_MAX_FINGERNUM;
if (fpi_byte_reader_skip (byte_reader, 1))
fpi_byte_reader_get_uint8 (byte_reader,
&presp->finger_config.max_stored_prints);
}
break;
@@ -322,85 +319,100 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint16_t buffer_len, pgxfp_c
case MOC_CMD0_PWR_BTN_SHIELD:
presp->power_button_shield_resp.resp_cmd1 = LOBYTE (cmd);
if (buffer_len >= 2)
{
uint8_t support_pwr_shield = buffer[1];
if (support_pwr_shield == 0xFF)
g_debug ("Power button shield feature not supported!\n");
}
uint8_t support_pwr_shield;
if (fpi_byte_reader_get_uint8 (byte_reader, &support_pwr_shield) &&
support_pwr_shield == 0xFF)
g_debug ("Power button shield feature not supported!\n");
break;
case MOC_CMD0_GET_VERSION:
if (buffer_len < sizeof (gxfp_version_info_t) + 1)
return -1;
memcpy (&presp->version_info, buffer + 1, sizeof (gxfp_version_info_t));
const uint8_t *version_info;
if (!fpi_byte_reader_get_data (byte_reader, sizeof (gxfp_version_info_t), &version_info))
g_return_val_if_reached (-1);
memcpy (&presp->version_info, version_info, sizeof (gxfp_version_info_t));
break;
case MOC_CMD0_CAPTURE_DATA:
if (LOBYTE (cmd) == MOC_CMD1_DEFAULT)
{
if (buffer_len < sizeof (gxfp_capturedata_t) + 1)
return -1;
presp->capture_data_resp.img_quality = buffer[1];
presp->capture_data_resp.img_coverage = buffer[2];
if (!fpi_byte_reader_get_uint8 (byte_reader,
&presp->capture_data_resp.img_quality))
g_return_val_if_reached (-1);
if (!fpi_byte_reader_get_uint8 (byte_reader,
&presp->capture_data_resp.img_coverage))
g_return_val_if_reached (-1);
}
break;
case MOC_CMD0_ENROLL_INIT:
if (buffer_len < sizeof (gxfp_enroll_create_t) + 1)
return -1;
if (presp->result == GX_SUCCESS)
memcpy (&presp->enroll_create.tid, &buffer[1], TEMPLATE_ID_SIZE);
if (presp->result != GX_SUCCESS)
break;
const uint8_t *tid;
if (!fpi_byte_reader_get_data (byte_reader, TEMPLATE_ID_SIZE, &tid))
g_return_val_if_reached (-1);
memcpy (presp->enroll_create.tid, tid, TEMPLATE_ID_SIZE);
break;
case MOC_CMD0_ENROLL:
if (buffer_len < sizeof (gxfp_enroll_update_t))
return -1;
presp->enroll_update.rollback = (buffer[0] < 0x80) ? false : true;
presp->enroll_update.img_overlay = buffer[1];
presp->enroll_update.img_preoverlay = buffer[2];
presp->enroll_update.rollback = (presp->result < 0x80) ? false : true;
if (!fpi_byte_reader_get_uint8 (byte_reader,
&presp->enroll_update.img_overlay))
g_return_val_if_reached (-1);
if (!fpi_byte_reader_get_uint8 (byte_reader,
&presp->enroll_update.img_preoverlay))
g_return_val_if_reached (-1);
break;
case MOC_CMD0_CHECK4DUPLICATE:
presp->check_duplicate_resp.duplicate = (presp->result == 0) ? false : true;
if (presp->check_duplicate_resp.duplicate)
{
if (buffer_len < 3)
return -1;
uint16_t tid_size = GUINT16_FROM_LE (*(uint16_t *) (buffer + 1));
offset += 3;
uint16_t tid_size;
const uint8_t *tid_data;
if (buffer_len < tid_size + offset)
return -1;
if (gx_proto_parse_fingerid (buffer + offset, tid_size, &presp->check_duplicate_resp.template) != 0)
return -1;
if (!fpi_byte_reader_get_uint16_le (byte_reader, &tid_size))
g_return_val_if_reached (-1);
if (!fpi_byte_reader_get_data (byte_reader, tid_size, &tid_data))
g_return_val_if_reached (-1);
if (gx_proto_parse_fingerid (tid_data, tid_size,
&presp->check_duplicate_resp.template) != 0)
g_return_val_if_reached (-1);
}
break;
case MOC_CMD0_GETFINGERLIST:
if (presp->result != GX_SUCCESS)
break;
if (buffer_len < 2)
return -1;
presp->finger_list_resp.finger_num = buffer[1];
fingerlist = buffer + 2;
if (!fpi_byte_reader_get_uint8 (byte_reader,
&presp->finger_list_resp.finger_num))
g_return_val_if_reached (-1);
for(uint8_t num = 0; num < presp->finger_list_resp.finger_num; num++)
{
uint16_t fingerid_length;
if (buffer_len < offset + 2)
return -1;
fingerid_length = GUINT16_FROM_LE (*(uint16_t *) (fingerlist + offset));
offset += 2;
if (buffer_len < fingerid_length + offset)
return -1;
if (gx_proto_parse_fingerid (fingerlist + offset,
const uint8_t *fingerid_data;
if (!fpi_byte_reader_get_uint16_le (byte_reader, &fingerid_length))
g_return_val_if_reached (-1);
if (!fpi_byte_reader_get_data (byte_reader, fingerid_length, &fingerid_data))
g_return_val_if_reached (-1);
if (gx_proto_parse_fingerid (fingerid_data,
fingerid_length,
&presp->finger_list_resp.finger_list[num]) != 0)
{
g_warning ("Failed to parse finger list");
return -1;
g_return_val_if_reached (-1);
}
offset += fingerid_length;
}
break;
@@ -409,23 +421,32 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint16_t buffer_len, pgxfp_c
uint32_t score = 0;
uint8_t study = 0;
uint16_t fingerid_size = 0;
presp->verify.match = (buffer[0] == 0) ? true : false;
presp->verify.match = (presp->result == 0) ? true : false;
if (presp->verify.match)
{
if (buffer_len < 10)
return -1;
offset += 1;
presp->verify.rejectdetail = GUINT16_FROM_LE (*(uint16_t *) (buffer + offset));
offset += 2;
score = GUINT32_FROM_LE (*(uint32_t *) (buffer + offset));
offset += 4;
study = buffer[offset];
offset += 1;
fingerid_size = GUINT16_FROM_LE (*(uint16_t *) (buffer + offset));
offset += 2;
if (buffer_len < fingerid_size + offset)
return -1;
if (gx_proto_parse_fingerid (buffer + offset, fingerid_size, &presp->verify.template) != 0)
const uint8_t *finger_data;
if (!fpi_byte_reader_get_uint16_le (byte_reader,
&presp->verify.rejectdetail))
g_return_val_if_reached (-1);
if (!fpi_byte_reader_get_uint32_le (byte_reader, &score))
g_return_val_if_reached (-1);
if (!fpi_byte_reader_get_uint8 (byte_reader, &study))
g_return_val_if_reached (-1);
if (!fpi_byte_reader_get_uint16_le (byte_reader, &fingerid_size))
g_return_val_if_reached (-1);
if (!fpi_byte_reader_get_data (byte_reader, fingerid_size,
&finger_data))
g_return_val_if_reached (-1);
if (gx_proto_parse_fingerid (finger_data, fingerid_size,
&presp->verify.template) != 0)
{
presp->result = GX_FAILED;
break;
@@ -436,7 +457,7 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint16_t buffer_len, pgxfp_c
break;
case MOC_CMD0_FINGER_MODE:
presp->finger_status.status = buffer[0];
presp->finger_status.status = presp->result;
break;
default:

View File

@@ -22,6 +22,8 @@
#include <stdbool.h>
#include <string.h>
#include "fpi-byte-reader.h"
#define PACKAGE_CRC_SIZE (4)
#define PACKAGE_HEADER_SIZE (8)
@@ -133,7 +135,7 @@ typedef struct _template_format
typedef struct _gxfp_verify
{
bool match;
uint32_t rejectdetail;
uint16_t rejectdetail;
template_format_t template;
} gxfp_verify_t, *pgxfp_verify_t;
@@ -237,8 +239,7 @@ int gx_proto_parse_header (uint8_t *buffer,
pack_header *pheader);
int gx_proto_parse_body (uint16_t cmd,
uint8_t *buffer,
uint16_t buffer_len,
FpiByteReader *byte_reader,
pgxfp_cmd_response_t presponse);
int gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig);