hog: fix invalid type cast in discover_descriptor_cb
PATCH 1/1 hog: fix invalid type cast in discover_descriptor_cb
the argument user_data for discover_descriptor_cb can be either a pointer to report or a pointer to hogdev, it is differentiate by uuid. when uuid is GATT_EXTERNAL_REPORT_REFERENCE and actual user_data is a pointer to a report, the user_data is wrongly cast to hogdev, hence cause memory corruption.
create another function discover_descriptor_no_report_cb, avoid type cast based on uuid fix the problem.
--- profiles/input/hog.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-)
profiles/input/hog.c +39 -4
@@ -219,7 +219,6 @@ static void discover_descriptor_cb(uint8_t status, GSList *descs, void *user_data) {struct report *report; -struct hog_device *hogdev;GAttrib *attrib =NULL ;if (status !=0 ) {
@@ -244,6 +243,41 @@ static void discover_descriptor_cb(uint8_t status, GSList *descs, report_reference_cb, report);break ;case GATT_EXTERNAL_REPORT_REFERENCE : +break ; + } + } +} + +static void discover_descriptor (GAttrib *attrib,uint16_t start,uint16_t end, +gpointer user_data) +{ +if (start > end) +return ; + +gatt_discover_desc (attrib, start, end,NULL , + discover_descriptor_cb, user_data); +} + +static void discover_descriptor_no_report_cb (uint8_t status,GSList *descs, +void *user_data) +{ +struct hog_device *hogdev; +GAttrib *attrib =NULL ; + +if (status !=0 ) { +error ("Discover all descriptors failed: %s" , +att_ecode2str (status)); +return ; + } + +for ( ; descs; descs = descs->next) { +struct gatt_desc *desc = descs->data; + +switch (desc->uuid16) { +case GATT_CLIENT_CHARAC_CFG_UUID : +case GATT_REPORT_REFERENCE : +break ; +case GATT_EXTERNAL_REPORT_REFERENCE : hogdev = user_data; attrib = hogdev->attrib; gatt_read_char(attrib, desc->handle,
@@ -253,16 +287,17 @@ static void discover_descriptor_cb(uint8_t status, GSList *descs, } } -static void discover_descriptor (GAttrib *attrib,uint16_t start,uint16_t end, +static void discover_descriptor_no_report (GAttrib *attrib,uint16_t start,uint16_t end,gpointer user_data) {if (start > end)return ;gatt_discover_desc (attrib, start, end,NULL , - discover_descriptor_cb, user_data); + discover_descriptor_no_report_cb, user_data); } +static void external_service_char_cb (uint8_t status,GSList *chars,void *user_data) {
@@ -824,7 +859,7 @@ static void char_discovered_cb(uint8_t status, GSList *chars, void *user_data)DBG ("HoG discovering report map" );gatt_read_char (hogdev->attrib, chr->value_handle, report_map_read_cb, hogdev); -discover_descriptor (hogdev->attrib, start, end, hogdev); +discover_descriptor_no_report (hogdev->attrib, start, end, hogdev); }else if (bt_uuid_cmp (&uuid, &info_uuid) ==0 ) info_handle = chr->value_handle;else if (bt_uuid_cmp (&uuid, &proto_mode_uuid) ==0 )
Signature · 1 line
1.9.1
Luiz Augusto von Dentz
maintainerHi,
Quoted 95 lines · Founder Fang
the argument
user_datafordiscover_descriptor_cbcan be either a pointer to report or a pointer to hogdev, it is differentiate by uuid. when uuid isGATT_EXTERNAL_REPORT_REFERENCEand actualuser_datais a pointer to a report, theuser_datais wrongly cast to hogdev, hence cause memory corruption.
create another functiondiscover_descriptor_no_report_cb, avoid type cast based on uuid fix the problem.--- profiles/input/hog.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-)profiles/input/hog.c +39
-5@@ -219,7 +219,6 @@ static void discover_descriptor_cb(uint8_t status, GSList *descs, void *user_data) {struct report *report; -struct hog_device *hogdev;GAttrib *attrib =NULL ;if (status !=0 ) {@@ -244,6 +243,41 @@ static void discover_descriptor_cb(uint8_t status, GSList *descs, report_reference_cb, report);break ;case GATT_EXTERNAL_REPORT_REFERENCE : +break ; + } + } +} + +static void discover_descriptor (GAttrib *attrib,uint16_t start,uint16_t end, +gpointer user_data) +{ +if (start > end) +return ; + +gatt_discover_desc (attrib, start, end,NULL , + discover_descriptor_cb, user_data); +} + +static void discover_descriptor_no_report_cb (uint8_t status,GSList *descs, +void *user_data) +{ +struct hog_device *hogdev; +GAttrib *attrib =NULL ; + +if (status !=0 ) { +error ("Discover all descriptors failed: %s" , +att_ecode2str (status)); +return ; + } + +for ( ; descs; descs = descs->next) { +struct gatt_desc *desc = descs->data; + +switch (desc->uuid16) { +case GATT_CLIENT_CHARAC_CFG_UUID : +case GATT_REPORT_REFERENCE : +break ; +case GATT_EXTERNAL_REPORT_REFERENCE : hogdev = user_data; attrib = hogdev->attrib; gatt_read_char(attrib, desc->handle,@@ -253,16 +287,17 @@ static void discover_descriptor_cb(uint8_t status, GSList *descs, } } -static void discover_descriptor (GAttrib *attrib,uint16_t start,uint16_t end, +static void discover_descriptor_no_report (GAttrib *attrib,uint16_t start,uint16_t end,gpointer user_data) {if (start > end)return ;gatt_discover_desc (attrib, start, end,NULL , - discover_descriptor_cb, user_data); + discover_descriptor_no_report_cb, user_data); } +static void external_service_char_cb (uint8_t status,GSList *chars,void *user_data) {@@ -824,7 +859,7 @@ static void char_discovered_cb(uint8_t status, GSList *chars, void *user_data)DBG ("HoG discovering report map" );gatt_read_char (hogdev->attrib, chr->value_handle, report_map_read_cb, hogdev); -discover_descriptor (hogdev->attrib, start, end, hogdev); +discover_descriptor_no_report (hogdev->attrib, start, end, hogdev); }else if (bt_uuid_cmp (&uuid, &info_uuid) ==0 ) info_handle = chr->value_handle;else if (bt_uuid_cmp (&uuid, &proto_mode_uuid) ==0 ) --
Quoted 1 line
1.9.1
Ive made a similar fix to android in 47a337152d342a37e3021dab0b18487b185e8b76, we should probably port that one to profile/input since in future we are planning to use to share the same implementation.
Signature · 1 line
Luiz Augusto von Dentz
Hi,
Quoted 96 lines · Luiz Augusto von Dentz
Hi,
Quoted 93 lines · Founder Fang
the argument
user_datafordiscover_descriptor_cbcan be either a pointer to report or a pointer to hogdev, it is differentiate by uuid. when uuid isGATT_EXTERNAL_REPORT_REFERENCEand actualuser_datais a pointer to a report, theuser_datais wrongly cast to hogdev, hence cause memory corruption.
create another functiondiscover_descriptor_no_report_cb, avoid type cast based on uuid fix the problem.--- profiles/input/hog.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-)profiles/input/hog.c +39
-4@@ -219,7 +219,6 @@ static void discover_descriptor_cb(uint8_t status, GSList *descs, void *user_data) {struct report *report; -struct hog_device *hogdev;GAttrib *attrib =NULL ;if (status !=0 ) {@@ -244,6 +243,41 @@ static void discover_descriptor_cb(uint8_t status, GSList *descs, report_reference_cb, report);break ;case GATT_EXTERNAL_REPORT_REFERENCE : +break ; + } + } +} + +static void discover_descriptor (GAttrib *attrib,uint16_t start,uint16_t end, +gpointer user_data) +{ +if (start > end) +return ; + +gatt_discover_desc (attrib, start, end,NULL , + discover_descriptor_cb, user_data); +} + +static void discover_descriptor_no_report_cb (uint8_t status,GSList *descs, +void *user_data) +{ +struct hog_device *hogdev; +GAttrib *attrib =NULL ; + +if (status !=0 ) { +error ("Discover all descriptors failed: %s" , +att_ecode2str (status)); +return ; + } + +for ( ; descs; descs = descs->next) { +struct gatt_desc *desc = descs->data; + +switch (desc->uuid16) { +case GATT_CLIENT_CHARAC_CFG_UUID : +case GATT_REPORT_REFERENCE : +break ; +case GATT_EXTERNAL_REPORT_REFERENCE : hogdev = user_data; attrib = hogdev->attrib; gatt_read_char(attrib, desc->handle,@@ -253,16 +287,17 @@ static void discover_descriptor_cb(uint8_t status, GSList *descs, } } -static void discover_descriptor (GAttrib *attrib,uint16_t start,uint16_t end, +static void discover_descriptor_no_report (GAttrib *attrib,uint16_t start,uint16_t end,gpointer user_data) {if (start > end)return ;gatt_discover_desc (attrib, start, end,NULL , - discover_descriptor_cb, user_data); + discover_descriptor_no_report_cb, user_data); } +static void external_service_char_cb (uint8_t status,GSList *chars,void *user_data) {@@ -824,7 +859,7 @@ static void char_discovered_cb(uint8_t status, GSList *chars, void *user_data)DBG ("HoG discovering report map" );gatt_read_char (hogdev->attrib, chr->value_handle, report_map_read_cb, hogdev); -discover_descriptor (hogdev->attrib, start, end, hogdev); +discover_descriptor_no_report (hogdev->attrib, start, end, hogdev); }else if (bt_uuid_cmp (&uuid, &info_uuid) ==0 ) info_handle = chr->value_handle;
Quoted 12 lines
Quoted 3 lines
profiles/input/hog.c +0
-1else if (bt_uuid_cmp (&uuid, &proto_mode_uuid) ==0 ) --1.9.1
Ive made a similar fix to android in
47a337152d342a37e3021dab0b18487b185e8b76, we should probably port that one to profile/input since in future we are planning to use to share the same implementation.Signature · 1 line
Luiz Augusto von Dentz
any plan to merge android/hog.c and profile/input/hog.c? i notice
recently there are important patches apply to profile/input/hog.c but not in android/hog.c, eg. 8e73a002848a6a2abcbd436ea8aac089320c13f2
Founder Fang