Bug 1166587 - Check OBEX packet length before accessing it, r=shuang

This commit is contained in:
Ben Tian 2015-05-21 14:11:20 +08:00
parent 10cf613c05
commit 62eb33f04b
4 changed files with 83 additions and 20 deletions

View File

@ -126,7 +126,7 @@ public:
class ObexHeaderSet
{
public:
ObexHeaderSet(uint8_t aOpcode) : mOpcode(aOpcode)
ObexHeaderSet()
{
}
@ -252,7 +252,6 @@ public:
}
private:
uint8_t mOpcode;
nsTArray<nsAutoPtr<ObexHeader> > mHeaders;
};

View File

@ -899,10 +899,19 @@ BluetoothOppManager::ServerDataHandler(UnixSocketBuffer* aMessage)
{
MOZ_ASSERT(NS_IsMainThread());
uint8_t opCode;
/**
* Ensure
* - valid access to data[0], i.e., opCode
* - received packet length smaller than max packet length
*/
int receivedLength = aMessage->GetSize();
const uint8_t* data = aMessage->GetData();
if (receivedLength < 1 || receivedLength > MAX_PACKET_LENGTH) {
ReplyError(ObexResponseCode::BadRequest);
return;
}
uint8_t opCode;
const uint8_t* data = aMessage->GetData();
if (mPutPacketReceivedLength > 0) {
opCode = mPutFinalFlag ? ObexRequestCode::PutFinal : ObexRequestCode::Put;
} else {
@ -918,12 +927,13 @@ BluetoothOppManager::ServerDataHandler(UnixSocketBuffer* aMessage)
}
}
ObexHeaderSet pktHeaders(opCode);
ObexHeaderSet pktHeaders;
if (opCode == ObexRequestCode::Connect) {
// Section 3.3.1 "Connect", IrOBEX 1.2
// [opcode:1][length:2][version:1][flags:1][MaxPktSizeWeCanReceive:2]
// [Headers:var]
if (!ParseHeaders(&data[7], receivedLength - 7, &pktHeaders)) {
if (receivedLength < 7 ||
!ParseHeaders(&data[7], receivedLength - 7, &pktHeaders)) {
ReplyError(ObexResponseCode::BadRequest);
return;
}
@ -933,7 +943,8 @@ BluetoothOppManager::ServerDataHandler(UnixSocketBuffer* aMessage)
} else if (opCode == ObexRequestCode::Abort) {
// Section 3.3.5 "Abort", IrOBEX 1.2
// [opcode:1][length:2][Headers:var]
if (!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
if (receivedLength < 3 ||
!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
ReplyError(ObexResponseCode::BadRequest);
return;
}
@ -943,7 +954,8 @@ BluetoothOppManager::ServerDataHandler(UnixSocketBuffer* aMessage)
} else if (opCode == ObexRequestCode::Disconnect) {
// Section 3.3.2 "Disconnect", IrOBEX 1.2
// [opcode:1][length:2][Headers:var]
if (!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
if (receivedLength < 3 ||
!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
ReplyError(ObexResponseCode::BadRequest);
return;
}
@ -1026,6 +1038,13 @@ BluetoothOppManager::ClientDataHandler(UnixSocketBuffer* aMessage)
{
MOZ_ASSERT(NS_IsMainThread());
// Ensure valid access to data[0], i.e., opCode
int receivedLength = aMessage->GetSize();
if (receivedLength < 1) {
BT_LOGR("Receive empty response packet");
return;
}
const uint8_t* data = aMessage->GetData();
uint8_t opCode = data[0];
@ -1083,6 +1102,13 @@ BluetoothOppManager::ClientDataHandler(UnixSocketBuffer* aMessage)
AfterOppConnected();
// Ensure valid access to remote information
if (receivedLength < 7) {
BT_LOGR("The length of connect response packet is invalid");
SendDisconnectRequest();
return;
}
// Keep remote information
mRemoteObexVersion = data[3];
mRemoteConnectionFlags = data[4];

View File

@ -183,17 +183,27 @@ BluetoothPbapManager::ReceiveSocketData(BluetoothSocket* aSocket,
{
MOZ_ASSERT(NS_IsMainThread());
const uint8_t* data = aMessage->GetData();
/**
* Ensure
* - valid access to data[0], i.e., opCode
* - received packet length smaller than max packet length
*/
int receivedLength = aMessage->GetSize();
uint8_t opCode = data[0];
if (receivedLength < 1 || receivedLength > MAX_PACKET_LENGTH) {
ReplyError(ObexResponseCode::BadRequest);
return;
}
ObexHeaderSet pktHeaders(opCode);
const uint8_t* data = aMessage->GetData();
uint8_t opCode = data[0];
ObexHeaderSet pktHeaders;
switch (opCode) {
case ObexRequestCode::Connect:
// Section 3.3.1 "Connect", IrOBEX 1.2
// [opcode:1][length:2][version:1][flags:1][MaxPktSizeWeCanReceive:2]
// [Headers:var]
if (!ParseHeaders(&data[7], receivedLength - 7, &pktHeaders)) {
if (receivedLength < 7 ||
!ParseHeaders(&data[7], receivedLength - 7, &pktHeaders)) {
ReplyError(ObexResponseCode::BadRequest);
return;
}
@ -213,7 +223,8 @@ BluetoothPbapManager::ReceiveSocketData(BluetoothSocket* aSocket,
// Section 3.3.2 "Disconnect" and Section 3.3.5 "Abort", IrOBEX 1.2
// The format of request packet of "Disconnect" and "Abort" are the same
// [opcode:1][length:2][Headers:var]
if (!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
if (receivedLength < 3 ||
!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
ReplyError(ObexResponseCode::BadRequest);
return;
}
@ -224,7 +235,8 @@ BluetoothPbapManager::ReceiveSocketData(BluetoothSocket* aSocket,
case ObexRequestCode::SetPath: {
// Section 3.3.6 "SetPath", IrOBEX 1.2
// [opcode:1][length:2][flags:1][contants:1][Headers:var]
if (!ParseHeaders(&data[5], receivedLength - 5, &pktHeaders)) {
if (receivedLength < 5 ||
!ParseHeaders(&data[5], receivedLength - 5, &pktHeaders)) {
ReplyError(ObexResponseCode::BadRequest);
return;
}

View File

@ -878,10 +878,19 @@ BluetoothOppManager::ServerDataHandler(UnixSocketBuffer* aMessage)
{
MOZ_ASSERT(NS_IsMainThread());
uint8_t opCode;
/**
* Ensure
* - valid access to data[0], i.e., opCode
* - received packet length smaller than max packet length
*/
int receivedLength = aMessage->GetSize();
const uint8_t* data = aMessage->GetData();
if (receivedLength < 1 || receivedLength > MAX_PACKET_LENGTH) {
ReplyError(ObexResponseCode::BadRequest);
return;
}
uint8_t opCode;
const uint8_t* data = aMessage->GetData();
if (mPutPacketReceivedLength > 0) {
opCode = mPutFinalFlag ? ObexRequestCode::PutFinal : ObexRequestCode::Put;
} else {
@ -897,12 +906,13 @@ BluetoothOppManager::ServerDataHandler(UnixSocketBuffer* aMessage)
}
}
ObexHeaderSet pktHeaders(opCode);
ObexHeaderSet pktHeaders;
if (opCode == ObexRequestCode::Connect) {
// Section 3.3.1 "Connect", IrOBEX 1.2
// [opcode:1][length:2][version:1][flags:1][MaxPktSizeWeCanReceive:2]
// [Headers:var]
if (!ParseHeaders(&data[7], receivedLength - 7, &pktHeaders)) {
if (receivedLength < 7 ||
!ParseHeaders(&data[7], receivedLength - 7, &pktHeaders)) {
ReplyError(ObexResponseCode::BadRequest);
return;
}
@ -912,7 +922,8 @@ BluetoothOppManager::ServerDataHandler(UnixSocketBuffer* aMessage)
} else if (opCode == ObexRequestCode::Abort) {
// Section 3.3.5 "Abort", IrOBEX 1.2
// [opcode:1][length:2][Headers:var]
if (!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
if (receivedLength < 3 ||
!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
ReplyError(ObexResponseCode::BadRequest);
return;
}
@ -922,7 +933,8 @@ BluetoothOppManager::ServerDataHandler(UnixSocketBuffer* aMessage)
} else if (opCode == ObexRequestCode::Disconnect) {
// Section 3.3.2 "Disconnect", IrOBEX 1.2
// [opcode:1][length:2][Headers:var]
if (!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
if (receivedLength < 3 ||
!ParseHeaders(&data[3], receivedLength - 3, &pktHeaders)) {
ReplyError(ObexResponseCode::BadRequest);
return;
}
@ -1005,6 +1017,13 @@ BluetoothOppManager::ClientDataHandler(UnixSocketBuffer* aMessage)
{
MOZ_ASSERT(NS_IsMainThread());
// Ensure valid access to data[0], i.e., opCode
int receivedLength = aMessage->GetSize();
if (receivedLength < 1) {
BT_LOGR("Receive empty response packet");
return;
}
const uint8_t* data = aMessage->GetData();
uint8_t opCode = data[0];
@ -1062,6 +1081,13 @@ BluetoothOppManager::ClientDataHandler(UnixSocketBuffer* aMessage)
AfterOppConnected();
// Ensure valid access to remote information
if (receivedLength < 7) {
BT_LOGR("The length of connect response packet is invalid");
SendDisconnectRequest();
return;
}
// Keep remote information
mRemoteObexVersion = data[3];
mRemoteConnectionFlags = data[4];