* [PATCH] hog: fix invalid type cast in discover_descriptor_cb
@ 2015-09-16 7:23 Founder Fang
2015-09-16 9:54 ` Luiz Augusto von Dentz
0 siblings, 1 reply; 3+ messages in thread
From: Founder Fang @ 2015-09-16 7:23 UTC (permalink / raw)
To: linux-bluetooth
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(-)
diff --git a/profiles/input/hog.c b/profiles/input/hog.c
index e006add..bea8637 100644
--- a/profiles/input/hog.c
+++ b/profiles/input/hog.c
@@ -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)
--
1.9.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] hog: fix invalid type cast in discover_descriptor_cb
2015-09-16 7:23 [PATCH] hog: fix invalid type cast in discover_descriptor_cb Founder Fang
@ 2015-09-16 9:54 ` Luiz Augusto von Dentz
2015-09-17 1:21 ` Founder Fang
0 siblings, 1 reply; 3+ messages in thread
From: Luiz Augusto von Dentz @ 2015-09-16 9:54 UTC (permalink / raw)
To: Founder Fang; +Cc: linux-bluetooth@vger.kernel.org
Hi,
On Wed, Sep 16, 2015 at 10:23 AM, Founder Fang <founder.fang@gmail.com> wrote:
> 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(-)
>
> diff --git a/profiles/input/hog.c b/profiles/input/hog.c
> index e006add..bea8637 100644
> --- a/profiles/input/hog.c
> +++ b/profiles/input/hog.c
> @@ -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)
> --
> 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.
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] hog: fix invalid type cast in discover_descriptor_cb
2015-09-16 9:54 ` Luiz Augusto von Dentz
@ 2015-09-17 1:21 ` Founder Fang
0 siblings, 0 replies; 3+ messages in thread
From: Founder Fang @ 2015-09-17 1:21 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
Hi,
On Wed, Sep 16, 2015 at 12:54:55PM +0300, Luiz Augusto von Dentz wrote:
> Hi,
>
> On Wed, Sep 16, 2015 at 10:23 AM, Founder Fang <founder.fang@gmail.com> wrote:
> > 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(-)
> >
> > diff --git a/profiles/input/hog.c b/profiles/input/hog.c
> > index e006add..bea8637 100644
> > --- a/profiles/input/hog.c
> > +++ b/profiles/input/hog.c
> > @@ -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)
> > --
> > 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.
>
>
> --
> 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
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2015-09-17 1:21 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-16 7:23 [PATCH] hog: fix invalid type cast in discover_descriptor_cb Founder Fang
2015-09-16 9:54 ` Luiz Augusto von Dentz
2015-09-17 1:21 ` Founder Fang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).