2010-03-11 21:57:33

by Daniel Abraham

[permalink] [raw]
Subject: Bug in parsing of SDP_ServiceSearchAttributeResponse?

Hi, this is my first time here, so I'm not sure about etiquette, or
if/where there's a BlueZ bug repository...

I'm using BlueZ 4.62, and I ran the command line "sdptool browse <BD
address>" against a remote computer. I got this error output: "Service
search failed: Success".

According to hcidump (attached), the SDP_ServiceSearchAttributeResponse
is malformed, but a different Bluetooth stack (IVT on Windows) is able
to report correctly the remote computer's available services.

So I'm guessing this is a parsing error or interoperability weakness in
BlueZ...? (Or, less likely but possible, a bug in the other 2 stacks?)

Thanks


Attachments:
sdptool-browse-error.hcidump (1.66 kB)

2010-03-14 20:40:30

by Marcel Holtmann

[permalink] [raw]
Subject: Re: Bug in parsing of SDP_ServiceSearchAttributeResponse?

Hi Daniel,

> > According to hcidump (attached), the SDP_ServiceSearchAttributeResponse
> > is malformed, but a different Bluetooth stack (IVT on Windows) is able
> > to report correctly the remote computer's available services.
>
> It could be that the different Bluetooth stacks fetch that information via
> a different request than ServiceSearchAttributes, or that it queries the
> services that it hopes to see individually rather than just the
> PublicBrowseGroup to get everything as in this case.
>
> > So I'm guessing this is a parsing error or interoperability weakness in
> > BlueZ...? (Or, less likely but possible, a bug in the other 2 stacks?)
>
> The PDU that the remote computer sends is truncated at the end of the
> first L2CAP frame (all the 0's that hcidump shows are just empty buffer as
> it does not check the actual frame length). But, each L2CAP frame is
> supposed to contain an entire PDU and when the data exceeds the MTU it
> sends a non zero Continuation State to enable the client to request more
> data.
>
> It might be that this computer was not expecting that the response would
> overflow the L2CAP frame and they didn't write the code to handle that,
> but in the meantime many services were added..

you can decode only HCI and L2CAP like this:

hcidump -r <file> -X -V hci l2cap

That will avoid involving the SDP parser and you see that it is one
L2CAP packet with 672 bytes in there (split over two ACL packets).

The remote stack is having a bug in L2CAP already anyway:

> ACL data: handle 11 flags 0x02 dlen 14
L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 0 clen 0
Success

It is mandatory for the config response to include the MTU size to
confirm the configured value.

The SDP protocol is pretty clear in how to handle splitting long PDUs
over multiple L2CAP frames. This remote stack doesn't do it at all.
BlueZ handles this properly.

I wouldn't be surprised that even if you see the packet in hcidump, the
kernel actually dropped it. And it never was handed out to the
application because it was not fragmented properly. Check dmesg if the
kernel dropped a packet.

Regards

Marcel



2010-03-14 20:16:59

by Iain Hibbert

[permalink] [raw]
Subject: Re: Bug in parsing of SDP_ServiceSearchAttributeResponse?

On Sun, 14 Mar 2010, Daniel Abraham wrote:

> > You can probably use "sdptool search" to find specific services ok?
>
> Actually "sdptool" is just an example, the real problem is that when
> BlueZ discovers that device, the SDP PDU truncation causes it to appear
> to be profile-less, so I can't actively connect to any service, only
> passively accept connections.

Well, I'm not sure how BlueZ works in this regard but my question covers
searching for a specific service in general - eg if you perform a
ServiceSearchAttribute with a specific UUID and possibly a limited
AttributeIDList then the response will be a whole lot smaller and probably
fit into the L2CAP packet..

> > Although sdptool has no way to increase the "Incoming MTU" on the SDP
> > connection, if you could work out how to do that it might allow more
> > information to be received (in lib/sdp.c:sdp_connect_l2cap() set
> > L2CAP_OPTIONS with imtu at some large number than 672, before the
> > connect())
>
> Although the PDU truncation is a bug not in BlueZ, I still think it
> uncovers a point for improvement in BlueZ.
>
> Up until the truncation point, the PDU still contains 6-7 valid
> attribute lists, which are discarded. Why not use them despite the
> malformed PDU?

The code that parses the response from the remote side is told that there
are XXX bytes in the following data, but only yyy are in the packet.. what
to do? Its obviously an error and you can't necessarily guess what the
other side intended to send..

On the other hand, if BlueZ were to set the MaximiumAttributeByteCount to
a lower value (eg see patch below), that might help your remote device to
do the right thing.. if that works, the count could be calculated at
runtime as

MTU - 5(pdu hdr) - 2(attr count) - 17(max cont state)

rather than using a fixed value.

iain

--- lib/sdp.c.orig 2010-03-14 19:56:19.000000000 +0000
+++ lib/sdp.c 2010-03-14 19:56:53.000000000 +0000
@@ -95,7 +95,7 @@
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }
};

-#define SDP_MAX_ATTR_LEN 65535
+#define SDP_MAX_ATTR_LEN 600

static sdp_data_t *sdp_copy_seq(sdp_data_t *data);
static int sdp_attr_add_new_with_length(sdp_record_t *rec,



2010-03-14 13:50:16

by Daniel Abraham

[permalink] [raw]
Subject: Re: Bug in parsing of SDP_ServiceSearchAttributeResponse?

> > So I'm guessing this is a parsing error or interoperability weakness in
> > BlueZ...? (Or, less likely but possible, a bug in the other 2 stacks?)
>
> The PDU that the remote computer sends is truncated at the end of the
> first L2CAP frame (all the 0's that hcidump shows are just empty buffer as
> it does not check the actual frame length). But, each L2CAP frame is
> supposed to contain an entire PDU and when the data exceeds the MTU it
> sends a non zero Continuation State to enable the client to request more
> data.
>
> It might be that this computer was not expecting that the response would
> overflow the L2CAP frame and they didn't write the code to handle that,
> but in the meantime many services were added..

Thanks! This is exactly the pointer I was looking for. I didn't
understand your answer at first, but it led me to study the right
section in the BT spec, so now I get it.

> You can probably use "sdptool search" to find specific services ok?

Actually "sdptool" is just an example, the real problem is that when
BlueZ discovers that device, the SDP PDU truncation causes it to appear
to be profile-less, so I can't actively connect to any service, only
passively accept connections.

> Although sdptool has no way to increase the "Incoming MTU" on the SDP
> connection, if you could work out how to do that it might allow more
> information to be received (in lib/sdp.c:sdp_connect_l2cap() set
> L2CAP_OPTIONS with imtu at some large number than 672, before the
> connect())

Although the PDU truncation is a bug not in BlueZ, I still think it uncovers a point for improvement in BlueZ.

Up until the truncation point, the PDU still contains 6-7 valid attribute lists, which are discarded. Why not use them despite the malformed PDU?

Thanks again


2010-03-12 00:04:14

by Iain Hibbert

[permalink] [raw]
Subject: Re: Bug in parsing of SDP_ServiceSearchAttributeResponse?

On Thu, 11 Mar 2010, Daniel Abraham wrote:

> Hi, this is my first time here, so I'm not sure about etiquette, or
> if/where there's a BlueZ bug repository...
>
> I'm using BlueZ 4.62, and I ran the command line "sdptool browse <BD
> address>" against a remote computer. I got this error output: "Service
> search failed: Success".

what computer is that?

> According to hcidump (attached), the SDP_ServiceSearchAttributeResponse
> is malformed, but a different Bluetooth stack (IVT on Windows) is able
> to report correctly the remote computer's available services.

It could be that the different Bluetooth stacks fetch that information via
a different request than ServiceSearchAttributes, or that it queries the
services that it hopes to see individually rather than just the
PublicBrowseGroup to get everything as in this case.

> So I'm guessing this is a parsing error or interoperability weakness in
> BlueZ...? (Or, less likely but possible, a bug in the other 2 stacks?)

The PDU that the remote computer sends is truncated at the end of the
first L2CAP frame (all the 0's that hcidump shows are just empty buffer as
it does not check the actual frame length). But, each L2CAP frame is
supposed to contain an entire PDU and when the data exceeds the MTU it
sends a non zero Continuation State to enable the client to request more
data.

It might be that this computer was not expecting that the response would
overflow the L2CAP frame and they didn't write the code to handle that,
but in the meantime many services were added..

You can probably use "sdptool search" to find specific services ok?

Although sdptool has no way to increase the "Incoming MTU" on the SDP
connection, if you could work out how to do that it might allow more
information to be received (in lib/sdp.c:sdp_connect_l2cap() set
L2CAP_OPTIONS with imtu at some large number than 672, before the
connect())

regards,
iain