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;  	}  | 
