summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2006-10-12 21:26:29 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2006-10-12 21:26:29 +0000
commit62e64a03e58854bf938c8c1a922365cb2076ac49 (patch)
tree12343eeec630ff893a0df3a3188e6057b0594ee5
parent5a6795edee5e8aa16c8b0aa6544b0ee1436d46a5 (diff)
Add extra checks for l2cap info request response parsing
-rw-r--r--hcid/dbus-test.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/hcid/dbus-test.c b/hcid/dbus-test.c
index c78baeee..7eed0f30 100644
--- a/hcid/dbus-test.c
+++ b/hcid/dbus-test.c
@@ -230,7 +230,7 @@ static gboolean l2raw_data_callback(GIOChannel *io, GIOCondition cond, struct au
l2cap_cmd_hdr *cmd = (l2cap_cmd_hdr *) buf;
l2cap_info_req *req = (l2cap_info_req *) (buf + L2CAP_CMD_HDR_SIZE);
l2cap_info_rsp *rsp = (l2cap_info_rsp *) (buf + L2CAP_CMD_HDR_SIZE);
- int sk;
+ int sk, ret, expected;
if (cond & G_IO_NVAL) {
g_io_channel_unref(io);
@@ -244,26 +244,45 @@ static gboolean l2raw_data_callback(GIOChannel *io, GIOCondition cond, struct au
memset(buf, 0, sizeof(buf));
- if (recv(sk, buf, L2CAP_CMD_HDR_SIZE + L2CAP_INFO_RSP_SIZE + 2, 0) < 0) {
+ if (audit->state == AUDIT_STATE_MTU)
+ expected = L2CAP_CMD_HDR_SIZE + L2CAP_INFO_RSP_SIZE + 2;
+ else
+ expected = L2CAP_CMD_HDR_SIZE + L2CAP_INFO_RSP_SIZE + 4;
+
+ ret = recv(sk, buf, expected, 0);
+ if (ret < 0) {
error("Can't receive info response: %s (%d)", strerror(errno), errno);
goto failed;
}
+ if (ret < L2CAP_CMD_HDR_SIZE) {
+ error("Too little data for l2cap response");
+ goto failed;
+ }
+
if (cmd->code != L2CAP_INFO_RSP)
return TRUE;
- if (audit->timeout) {
- g_timeout_remove(audit->timeout);
- audit->timeout = 0;
+ if (ret < expected) {
+ error("Too little data for l2cap info response");
+ goto failed;
}
switch (audit->state) {
case AUDIT_STATE_MTU:
+ if (rsp->type != htobs(0x0001))
+ return TRUE;
+
+ if (audit->timeout) {
+ g_timeout_remove(audit->timeout);
+ audit->timeout = 0;
+ }
+
handle_mtu_response(audit, rsp);
memset(buf, 0, sizeof(buf));
cmd->code = L2CAP_INFO_REQ;
- cmd->ident = 42;
+ cmd->ident = 43;
cmd->len = htobs(2);
req->type = htobs(0x0002);
@@ -280,6 +299,14 @@ static gboolean l2raw_data_callback(GIOChannel *io, GIOCondition cond, struct au
return TRUE;
case AUDIT_STATE_FEATURES:
+ if (rsp->type != htobs(0x0002))
+ return TRUE;
+
+ if (audit->timeout) {
+ g_timeout_remove(audit->timeout);
+ audit->timeout = 0;
+ }
+
handle_features_response(audit, rsp);
break;
}