linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH BlueZ 1/4] input: Change extract_hid_record() return type
@ 2013-01-06 19:45 Anderson Lizardo
  2013-01-06 19:45 ` [PATCH BlueZ 2/4] input: Move HID device name creation to separate function Anderson Lizardo
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Anderson Lizardo @ 2013-01-06 19:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Lizardo

This will allow returning error values when necessary.
---
 profiles/input/device.c |   11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/profiles/input/device.c b/profiles/input/device.c
index 759603a..9e485cf 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -202,7 +202,7 @@ static void epox_endian_quirk(unsigned char *data, int size)
 	}
 }
 
-static void extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req)
+static int extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req)
 {
 	sdp_data_t *pdlist, *pdlist2;
 	uint8_t attr_val;
@@ -255,6 +255,8 @@ static void extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req)
 			epox_endian_quirk(req->rd_data, req->rd_size);
 		}
 	}
+
+	return 0;
 }
 
 static int ioctl_connadd(struct hidp_connadd_req *req)
@@ -346,8 +348,13 @@ static int hidp_add_connection(struct input_device *idev)
 	rec = record_from_string(str);
 	g_free(str);
 
-	extract_hid_record(rec, req);
+	err = extract_hid_record(rec, req);
 	sdp_record_free(rec);
+	if (err < 0) {
+		error("Could not parse HID SDP record: %s (%d)", strerror(-err),
+									-err);
+		goto cleanup;
+	}
 
 	req->vendor = btd_device_get_vendor(idev->device);
 	req->product = btd_device_get_product(idev->device);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH BlueZ 2/4] input: Move HID device name creation to separate function
  2013-01-06 19:45 [PATCH BlueZ 1/4] input: Change extract_hid_record() return type Anderson Lizardo
@ 2013-01-06 19:45 ` Anderson Lizardo
  2013-01-06 19:45 ` [PATCH BlueZ 3/4] input: Use SDP library functions for reading attributes Anderson Lizardo
  2013-01-06 19:45 ` [PATCH BlueZ 4/4] input: Validate SDP HIDDescriptorList subattributes Anderson Lizardo
  2 siblings, 0 replies; 6+ messages in thread
From: Anderson Lizardo @ 2013-01-06 19:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Lizardo

The attributes used for composing the device name are all optional, and
thus need to be properly validated. A separate function will avoid
polluting the caller with variables used only for device name
composition.
---
 profiles/input/device.c |   16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/profiles/input/device.c b/profiles/input/device.c
index 9e485cf..7a7e995 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -202,10 +202,9 @@ static void epox_endian_quirk(unsigned char *data, int size)
 	}
 }
 
-static int extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req)
+static int create_hid_dev_name(sdp_record_t *rec, struct hidp_connadd_req *req)
 {
 	sdp_data_t *pdlist, *pdlist2;
-	uint8_t attr_val;
 
 	pdlist = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY);
 	pdlist2 = sdp_data_get(rec, SDP_ATTR_PROVNAME_PRIMARY);
@@ -222,6 +221,19 @@ static int extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req)
 							pdlist->val.str);
 	}
 
+	return 0;
+}
+
+static int extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req)
+{
+	sdp_data_t *pdlist;
+	uint8_t attr_val;
+	int err;
+
+	err = create_hid_dev_name(rec, req);
+	if (err < 0)
+		DBG("No valid Service Name or Service Description found");
+
 	pdlist = sdp_data_get(rec, SDP_ATTR_HID_PARSER_VERSION);
 	req->parser = pdlist ? pdlist->val.uint16 : 0x0100;
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH BlueZ 3/4] input: Use SDP library functions for reading attributes
  2013-01-06 19:45 [PATCH BlueZ 1/4] input: Change extract_hid_record() return type Anderson Lizardo
  2013-01-06 19:45 ` [PATCH BlueZ 2/4] input: Move HID device name creation to separate function Anderson Lizardo
@ 2013-01-06 19:45 ` Anderson Lizardo
  2013-01-06 19:45 ` [PATCH BlueZ 4/4] input: Validate SDP HIDDescriptorList subattributes Anderson Lizardo
  2 siblings, 0 replies; 6+ messages in thread
From: Anderson Lizardo @ 2013-01-06 19:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Lizardo

These functions do the necessary validation that is lacking from
previous code.
---
 profiles/input/device.c |   26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/profiles/input/device.c b/profiles/input/device.c
index 7a7e995..eaf5681 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -204,21 +204,19 @@ static void epox_endian_quirk(unsigned char *data, int size)
 
 static int create_hid_dev_name(sdp_record_t *rec, struct hidp_connadd_req *req)
 {
-	sdp_data_t *pdlist, *pdlist2;
-
-	pdlist = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY);
-	pdlist2 = sdp_data_get(rec, SDP_ATTR_PROVNAME_PRIMARY);
-	if (pdlist && pdlist2 &&
-			strncmp(pdlist->val.str, pdlist2->val.str, 5) != 0) {
-		snprintf(req->name, sizeof(req->name), "%s %s",
-					pdlist2->val.str, pdlist->val.str);
-	} else {
-		if (!pdlist)
-			pdlist = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY);
+	char sdesc[sizeof(req->name)];
+
+	if (sdp_get_service_desc(rec, sdesc, sizeof(sdesc)) == 0) {
+		char pname[sizeof(req->name)];
 
-		if (pdlist)
-			snprintf(req->name, sizeof(req->name), "%s",
-							pdlist->val.str);
+		if (sdp_get_provider_name(rec, pname, sizeof(pname)) == 0 &&
+						strncmp(sdesc, pname, 5) != 0)
+			snprintf(req->name, sizeof(req->name), "%s %s", pname,
+									sdesc);
+		else
+			snprintf(req->name, sizeof(req->name), "%s", sdesc);
+	} else {
+		return sdp_get_service_name(rec, req->name, sizeof(req->name));
 	}
 
 	return 0;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH BlueZ 4/4] input: Validate SDP HIDDescriptorList subattributes
  2013-01-06 19:45 [PATCH BlueZ 1/4] input: Change extract_hid_record() return type Anderson Lizardo
  2013-01-06 19:45 ` [PATCH BlueZ 2/4] input: Move HID device name creation to separate function Anderson Lizardo
  2013-01-06 19:45 ` [PATCH BlueZ 3/4] input: Use SDP library functions for reading attributes Anderson Lizardo
@ 2013-01-06 19:45 ` Anderson Lizardo
  2013-01-07  8:27   ` Johan Hedberg
  2 siblings, 1 reply; 6+ messages in thread
From: Anderson Lizardo @ 2013-01-06 19:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Lizardo

It should not be assumed that remote SDP attributes are in a compliant
format. This fixes a couple of invalid pointer access on invalid data.
---
 profiles/input/device.c |   60 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 46 insertions(+), 14 deletions(-)

diff --git a/profiles/input/device.c b/profiles/input/device.c
index eaf5681..bd32623 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -222,6 +222,49 @@ static int create_hid_dev_name(sdp_record_t *rec, struct hidp_connadd_req *req)
 	return 0;
 }
 
+/* See HID profile specification v1.0, "7.11.6 HIDDescriptorList" for details
+ * on the attribute format. */
+static int extract_hid_desc_data(sdp_record_t *rec,
+						struct hidp_connadd_req *req)
+{
+	sdp_data_t *d;
+
+	d = sdp_data_get(rec, SDP_ATTR_HID_DESCRIPTOR_LIST);
+	if (!d)
+		goto invalid_desc;
+
+	if (d->dtd < SDP_SEQ8 || d->dtd > SDP_SEQ32)
+		goto invalid_desc;
+
+	/* First HIDDescriptor */
+	d = d->val.dataseq;
+	if (d->dtd < SDP_SEQ8 || d->dtd > SDP_SEQ32)
+		goto invalid_desc;
+
+	/* ClassDescriptorType */
+	d = d->val.dataseq;
+	if (d->dtd != SDP_UINT8)
+		goto invalid_desc;
+
+	/* ClassDescriptorData */
+	d = d->next;
+	if (!d || d->dtd < SDP_TEXT_STR8 || d->dtd > SDP_TEXT_STR32)
+		goto invalid_desc;
+
+	req->rd_data = g_try_malloc0(d->unitSize);
+	if (req->rd_data) {
+		memcpy(req->rd_data, d->val.str, d->unitSize);
+		req->rd_size = d->unitSize;
+		epox_endian_quirk(req->rd_data, req->rd_size);
+	}
+
+	return 0;
+
+invalid_desc:
+	error("Missing or invalid HIDDescriptorList SDP attribute");
+	return -EINVAL;
+}
+
 static int extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req)
 {
 	sdp_data_t *pdlist;
@@ -251,20 +294,9 @@ static int extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req)
 	if (attr_val)
 		req->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE);
 
-	pdlist = sdp_data_get(rec, SDP_ATTR_HID_DESCRIPTOR_LIST);
-	if (pdlist) {
-		pdlist = pdlist->val.dataseq;
-		pdlist = pdlist->val.dataseq;
-		pdlist = pdlist->next;
-
-		req->rd_data = g_try_malloc0(pdlist->unitSize);
-		if (req->rd_data) {
-			memcpy(req->rd_data, (unsigned char *) pdlist->val.str,
-								pdlist->unitSize);
-			req->rd_size = pdlist->unitSize;
-			epox_endian_quirk(req->rd_data, req->rd_size);
-		}
-	}
+	err = extract_hid_desc_data(rec, req);
+	if (err < 0)
+		return err;
 
 	return 0;
 }
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH BlueZ 4/4] input: Validate SDP HIDDescriptorList subattributes
  2013-01-06 19:45 ` [PATCH BlueZ 4/4] input: Validate SDP HIDDescriptorList subattributes Anderson Lizardo
@ 2013-01-07  8:27   ` Johan Hedberg
  2013-01-07 11:59     ` Anderson Lizardo
  0 siblings, 1 reply; 6+ messages in thread
From: Johan Hedberg @ 2013-01-07  8:27 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth

Hi Lizardo,

On Sun, Jan 06, 2013, Anderson Lizardo wrote:
> It should not be assumed that remote SDP attributes are in a compliant
> format. This fixes a couple of invalid pointer access on invalid data.
> ---
>  profiles/input/device.c |   60 ++++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 46 insertions(+), 14 deletions(-)

I've applied the first three patches, but this one needs a bit of fixing
up:

> +	if (d->dtd < SDP_SEQ8 || d->dtd > SDP_SEQ32)
> +		goto invalid_desc;

Please always be explicit on what values you're checking for instead of
assuming that the reader of the code knows what's contained within some
range. In this case there's already a convenient SDP_IS_SEQ() macro you
could use.

> +	if (d->dtd < SDP_SEQ8 || d->dtd > SDP_SEQ32)
> +		goto invalid_desc;

Same here.

> +	if (!d || d->dtd < SDP_TEXT_STR8 || d->dtd > SDP_TEXT_STR32)
> +		goto invalid_desc;

I suppose the best way to handle this one is to add a SDP_IS_STR() macro
(in a separate patch) to lib/sdp.h and then use it in this patch.

Johan

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH BlueZ 4/4] input: Validate SDP HIDDescriptorList subattributes
  2013-01-07  8:27   ` Johan Hedberg
@ 2013-01-07 11:59     ` Anderson Lizardo
  0 siblings, 0 replies; 6+ messages in thread
From: Anderson Lizardo @ 2013-01-07 11:59 UTC (permalink / raw)
  To: Anderson Lizardo, linux-bluetooth

Hi Johan,

On Mon, Jan 7, 2013 at 4:27 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
>> +     if (d->dtd < SDP_SEQ8 || d->dtd > SDP_SEQ32)
>> +             goto invalid_desc;
>
> Please always be explicit on what values you're checking for instead of
> assuming that the reader of the code knows what's contained within some
> range. In this case there's already a convenient SDP_IS_SEQ() macro you
> could use.
>
>> +     if (d->dtd < SDP_SEQ8 || d->dtd > SDP_SEQ32)
>> +             goto invalid_desc;
>
> Same here.
>
>> +     if (!d || d->dtd < SDP_TEXT_STR8 || d->dtd > SDP_TEXT_STR32)
>> +             goto invalid_desc;
>
> I suppose the best way to handle this one is to add a SDP_IS_STR() macro
> (in a separate patch) to lib/sdp.h and then use it in this patch.

Just sent a couple of patches fixing these problems and similar ones
in lib/sdp.c and health plugin source.

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-01-07 11:59 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-06 19:45 [PATCH BlueZ 1/4] input: Change extract_hid_record() return type Anderson Lizardo
2013-01-06 19:45 ` [PATCH BlueZ 2/4] input: Move HID device name creation to separate function Anderson Lizardo
2013-01-06 19:45 ` [PATCH BlueZ 3/4] input: Use SDP library functions for reading attributes Anderson Lizardo
2013-01-06 19:45 ` [PATCH BlueZ 4/4] input: Validate SDP HIDDescriptorList subattributes Anderson Lizardo
2013-01-07  8:27   ` Johan Hedberg
2013-01-07 11:59     ` Anderson Lizardo

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).