diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2006-10-12 21:26:29 +0000 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2006-10-12 21:26:29 +0000 |
commit | 62e64a03e58854bf938c8c1a922365cb2076ac49 (patch) | |
tree | 12343eeec630ff893a0df3a3188e6057b0594ee5 | |
parent | 5a6795edee5e8aa16c8b0aa6544b0ee1436d46a5 (diff) |
Add extra checks for l2cap info request response parsing
-rw-r--r-- | hcid/dbus-test.c | 39 |
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; } |