linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).