diff options
author | Jacob Keeler <jacob.keeler@livioradio.com> | 2019-05-29 15:30:05 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-29 15:30:05 -0400 |
commit | 98a47ee6a226716f4a8ede2213493838852753a8 (patch) | |
tree | 4e0bf772f3b7e3d38c9b56e840f52af718374d5b | |
parent | 692bffe47c0a95255f9c4efa652e679758fb856d (diff) | |
parent | ebde39ee1cec660dc255db38ba7347c9cf0e7360 (diff) | |
download | sdl_core-98a47ee6a226716f4a8ede2213493838852753a8.tar.gz |
Merge pull request #2786 from XevoInc/fix/buffer_overrun_bson_parsing
Avoid out-of-bound access while reading corrupted BSON field
-rw-r--r-- | src/components/protocol_handler/src/protocol_handler_impl.cc | 112 |
1 files changed, 71 insertions, 41 deletions
diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc index 944d80d5d9..518509a0fb 100644 --- a/src/components/protocol_handler/src/protocol_handler_impl.cc +++ b/src/components/protocol_handler/src/protocol_handler_impl.cc @@ -1501,11 +1501,18 @@ uint32_t get_hash_id(const ProtocolPacket& packet) { return HASH_ID_WRONG; } if (packet.protocol_version() >= PROTOCOL_VERSION_5) { - BsonObject obj = bson_object_from_bytes(packet.data()); - const uint32_t hash_id = - (uint32_t)bson_object_get_int32(&obj, strings::hash_id); - bson_object_deinitialize(&obj); - return hash_id; + BsonObject obj; + size_t obj_size = bson_object_from_bytes_len( + &obj, packet.data(), packet.total_data_bytes()); + if (obj_size > 0) { + const uint32_t hash_id = + (uint32_t)bson_object_get_int32(&obj, strings::hash_id); + bson_object_deinitialize(&obj); + return hash_id; + } else { + LOG4CXX_WARN(logger_, "Failed to parse BSON field for hash ID"); + return HASH_ID_WRONG; + } } else { const uint32_t hash_be = *(reinterpret_cast<uint32_t*>(packet.data())); const uint32_t hash_le = BE_TO_LE32(hash_be); @@ -1637,7 +1644,13 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession( BsonObject bson_obj; if (packet->data() != NULL) { - bson_obj = bson_object_from_bytes(packet->data()); + size_t bson_obj_size = bson_object_from_bytes_len( + &bson_obj, packet->data(), packet->total_data_bytes()); + if (bson_obj_size == 0) { + LOG4CXX_WARN(logger_, + "Failed to parse BSON field of start service packet"); + bson_object_initialize_default(&bson_obj); + } } else { bson_object_initialize_default(&bson_obj); } @@ -1730,33 +1743,42 @@ void ProtocolHandlerImpl::NotifySessionStarted( // when video service is successfully started, copy input parameters // ("width", "height", "videoProtocol", "videoCodec") to the ACK packet if (packet->service_type() == kMobileNav && packet->data() != NULL) { - BsonObject req_param = bson_object_from_bytes(packet->data()); - BsonElement* element = NULL; - - if ((element = bson_object_get(&req_param, strings::height)) != NULL && - element->type == TYPE_INT32) { - bson_object_put_int32(start_session_ack_params.get(), - strings::height, - bson_object_get_int32(&req_param, strings::height)); - } - if ((element = bson_object_get(&req_param, strings::width)) != NULL && - element->type == TYPE_INT32) { - bson_object_put_int32(start_session_ack_params.get(), - strings::width, - bson_object_get_int32(&req_param, strings::width)); - } - char* protocol = - bson_object_get_string(&req_param, strings::video_protocol); - if (protocol != NULL) { - bson_object_put_string( - start_session_ack_params.get(), strings::video_protocol, protocol); - } - char* codec = bson_object_get_string(&req_param, strings::video_codec); - if (codec != NULL) { - bson_object_put_string( - start_session_ack_params.get(), strings::video_codec, codec); + BsonObject req_param; + size_t req_param_size = bson_object_from_bytes_len( + &req_param, packet->data(), packet->total_data_bytes()); + if (req_param_size > 0) { + BsonElement* element = NULL; + + if ((element = bson_object_get(&req_param, strings::height)) != NULL && + element->type == TYPE_INT32) { + bson_object_put_int32( + start_session_ack_params.get(), + strings::height, + bson_object_get_int32(&req_param, strings::height)); + } + if ((element = bson_object_get(&req_param, strings::width)) != NULL && + element->type == TYPE_INT32) { + bson_object_put_int32( + start_session_ack_params.get(), + strings::width, + bson_object_get_int32(&req_param, strings::width)); + } + char* protocol = + bson_object_get_string(&req_param, strings::video_protocol); + if (protocol != NULL) { + bson_object_put_string( + start_session_ack_params.get(), strings::video_protocol, protocol); + } + char* codec = bson_object_get_string(&req_param, strings::video_codec); + if (codec != NULL) { + bson_object_put_string( + start_session_ack_params.get(), strings::video_codec, codec); + } + bson_object_deinitialize(&req_param); + } else { + LOG4CXX_WARN(logger_, + "Failed to parse BSON field of start service (video)"); } - bson_object_deinitialize(&req_param); } std::shared_ptr<utils::SemanticVersion> fullVersion; @@ -1765,16 +1787,24 @@ void ProtocolHandlerImpl::NotifySessionStarted( // could still be a payload, in which case we can get the real protocol // version if (packet->service_type() == kRpc && packet->data() != NULL) { - BsonObject request_params = bson_object_from_bytes(packet->data()); - char* version_param = - bson_object_get_string(&request_params, strings::protocol_version); - std::string version_string(version_param == NULL ? "" : version_param); - fullVersion = std::make_shared<utils::SemanticVersion>(version_string); - // Constructed payloads added in Protocol v5 - if (fullVersion->major_version_ < PROTOCOL_VERSION_5) { - rejected_params.push_back(std::string(strings::protocol_version)); + BsonObject request_params; + size_t request_params_size = bson_object_from_bytes_len( + &request_params, packet->data(), packet->total_data_bytes()); + if (request_params_size > 0) { + char* version_param = + bson_object_get_string(&request_params, strings::protocol_version); + std::string version_string(version_param == NULL ? "" : version_param); + fullVersion = std::make_shared<utils::SemanticVersion>(version_string); + // Constructed payloads added in Protocol v5 + if (fullVersion->major_version_ < PROTOCOL_VERSION_5) { + rejected_params.push_back(std::string(strings::protocol_version)); + } + bson_object_deinitialize(&request_params); + } else { + LOG4CXX_WARN(logger_, + "Failed to parse start service packet for version string"); + fullVersion = std::make_shared<utils::SemanticVersion>(); } - bson_object_deinitialize(&request_params); } else { fullVersion = std::make_shared<utils::SemanticVersion>(); } |