Loading system/gd/l2cap/l2cap_packet_test.cc +18 −0 Original line number Diff line number Diff line Loading @@ -61,5 +61,23 @@ DEFINE_AND_INSTANTIATE_GroupFrameReflectionTest(g_frame); std::vector<uint8_t> config_mtu_request = {0x04, 0x05, 0x08, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x02, 0xa0, 0x02}; DEFINE_AND_INSTANTIATE_ConfigurationRequestReflectionTest(config_mtu_request); DEFINE_ConfigurationRequestReflectionFuzzTest(); TEST(L2capFuzzRegressions, ConfigurationRequestFuzz_5691566077247488) { uint8_t bluetooth_gd_fuzz_test_5691566077247488[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; RunConfigurationRequestReflectionFuzzTest(bluetooth_gd_fuzz_test_5691566077247488, sizeof(bluetooth_gd_fuzz_test_5691566077247488)); } TEST(L2capFuzzRegressions, ConfigurationRequestFuzz_5747922062802944) { uint8_t bluetooth_gd_fuzz_test_5747922062802944[] = { 0x04, 0x02, 0x02, 0x7f, 0x3f, 0x7f, 0x3f, 0x7e, 0x7f, }; RunConfigurationRequestReflectionFuzzTest(bluetooth_gd_fuzz_test_5747922062802944, sizeof(bluetooth_gd_fuzz_test_5747922062802944)); } } // namespace l2cap } // namespace bluetooth system/gd/packet/parser/size.h +2 −1 Original line number Diff line number Diff line Loading @@ -79,7 +79,8 @@ class Size { } int bytes() const { return bits_ / 8; // Round up to the nearest byte return (bits_ + 7) / 8; } Size operator+(int rhs) { Loading system/gd/packet/parser/struct_def.cc +17 −6 Original line number Diff line number Diff line Loading @@ -89,18 +89,29 @@ void StructDef::GenParse(std::ostream& s) const { s << "{ return struct_begin_it.Subrange(0,0);}"; } Size total_bits{0}; for (const auto& field : fields_) { if (field->GetFieldType() != ReservedField::kFieldType && field->GetFieldType() != BodyField::kFieldType && field->GetFieldType() != FixedScalarField::kFieldType && field->GetFieldType() != SizeField::kFieldType && field->GetFieldType() != ChecksumStartField::kFieldType && field->GetFieldType() != ChecksumField::kFieldType && field->GetFieldType() != CountField::kFieldType) { total_bits += field->GetSize().bits(); } } s << "{"; s << "if (to_bound.NumBytesRemaining() < " << field->GetSize().bytes() << ")"; s << "if (to_bound.NumBytesRemaining() < " << total_bits.bytes() << ")"; if (!fields_.HasBody()) { s << "{ return to_bound.Subrange(to_bound.NumBytesRemaining(),0);}"; } else { s << "{ return {};}"; } s << "}"; for (const auto& field : fields_) { if (field->GetFieldType() != ReservedField::kFieldType && field->GetFieldType() != BodyField::kFieldType && field->GetFieldType() != FixedScalarField::kFieldType && field->GetFieldType() != SizeField::kFieldType && field->GetFieldType() != ChecksumStartField::kFieldType && field->GetFieldType() != ChecksumField::kFieldType && field->GetFieldType() != CountField::kFieldType) { s << "{"; int num_leading_bits = field->GenBounds(s, GetStructOffsetForField(field->GetName()), Size(), field->GetStructSize()); s << "auto " << field->GetName() << "_ptr = &to_fill->" << field->GetName() << "_;"; Loading system/gd/packet/parser/test/generated_packet_test.cc +26 −4 Original line number Diff line number Diff line Loading @@ -1667,15 +1667,15 @@ TEST(GeneratedPacketTest, testOneGenericStructFourArray) { parent_vector[3] = std::move(fbs); std::array<std::unique_ptr<UnusedParentStruct>, 4> vector_copy; size_t i = 0; size_t index = 0; for (auto& s : parent_vector) { if (s->struct_type_ == StructType::TWO_BYTE) { vector_copy[i] = std::make_unique<TwoByteStruct>(*(TwoByteStruct*)s.get()); vector_copy[index] = std::make_unique<TwoByteStruct>(*(TwoByteStruct*)s.get()); } if (s->struct_type_ == StructType::FOUR_BYTE) { vector_copy[i] = std::make_unique<FourByteStruct>(*(FourByteStruct*)s.get()); vector_copy[index] = std::make_unique<FourByteStruct>(*(FourByteStruct*)s.get()); } i++; index++; } auto packet = OneGenericStructFourArrayBuilder::Create(std::move(parent_vector)); Loading Loading @@ -1877,6 +1877,28 @@ TEST(GeneratedPacketTest, testByteSizedFields) { DEFINE_AND_INSTANTIATE_ByteSizedFieldsReflectionTest(byte_sized); TEST(GeneratedPacketTest, testOneGenericStructArrayNoZeroEmpty) { auto too_few_bytes = std::make_shared<std::vector<uint8_t>>(0); auto view = OneGenericStructArrayNoZeroView::Create(too_few_bytes); for (size_t i = 0; i < 10; i++) { if (view.IsValid()) { view.GetAnArray().size(); } too_few_bytes->push_back(0); view = OneGenericStructArrayNoZeroView::Create(too_few_bytes); } std::vector<uint8_t> a_two_byte_struct = { static_cast<uint8_t>(StructTypeNoZero::TWO_BYTE), 0x01, 0x02, }; too_few_bytes = std::make_shared<std::vector<uint8_t>>(a_two_byte_struct); view = OneGenericStructArrayNoZeroView::Create(too_few_bytes); ASSERT(view.IsValid()); ASSERT_EQ(1, view.GetAnArray().size()); } } // namespace parser } // namespace packet } // namespace bluetooth system/gd/packet/parser/test/test_packets.pdl +35 −0 Original line number Diff line number Diff line Loading @@ -405,3 +405,38 @@ packet ByteSizedFields { seven : 56, eight : 64, } enum StructTypeNoZero : 4 { TWO_BYTE = 0x02, FOUR_BYTE = 0x04, AT_LEAST_FOUR_BYTE = 0x05, } struct UnusedParentStructNoZero { struct_type : StructTypeNoZero, _reserved_ : 4, length : 8, _body_, } struct TwoByteStructNoZero : UnusedParentStructNoZero (struct_type = TWO_BYTE, length = 2) { two_bytes : 16, } struct FourByteStructNoZero : UnusedParentStructNoZero (struct_type = FOUR_BYTE, length = 4) { four_bytes : 32, } struct AtLeastFourByteStructNoZero : UnusedParentStructNoZero (struct_type = AT_LEAST_FOUR_BYTE) { four_bytes : 32, struct_type : StructTypeNoZero, _body_, } struct EightByteStructNoZero : AtLeastFourByteStructNoZero (struct_type = FOUR_BYTE, length = 9) { four_bytes : 32, } packet OneGenericStructArrayNoZero { an_array : UnusedParentStructNoZero[], } Loading
system/gd/l2cap/l2cap_packet_test.cc +18 −0 Original line number Diff line number Diff line Loading @@ -61,5 +61,23 @@ DEFINE_AND_INSTANTIATE_GroupFrameReflectionTest(g_frame); std::vector<uint8_t> config_mtu_request = {0x04, 0x05, 0x08, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x02, 0xa0, 0x02}; DEFINE_AND_INSTANTIATE_ConfigurationRequestReflectionTest(config_mtu_request); DEFINE_ConfigurationRequestReflectionFuzzTest(); TEST(L2capFuzzRegressions, ConfigurationRequestFuzz_5691566077247488) { uint8_t bluetooth_gd_fuzz_test_5691566077247488[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; RunConfigurationRequestReflectionFuzzTest(bluetooth_gd_fuzz_test_5691566077247488, sizeof(bluetooth_gd_fuzz_test_5691566077247488)); } TEST(L2capFuzzRegressions, ConfigurationRequestFuzz_5747922062802944) { uint8_t bluetooth_gd_fuzz_test_5747922062802944[] = { 0x04, 0x02, 0x02, 0x7f, 0x3f, 0x7f, 0x3f, 0x7e, 0x7f, }; RunConfigurationRequestReflectionFuzzTest(bluetooth_gd_fuzz_test_5747922062802944, sizeof(bluetooth_gd_fuzz_test_5747922062802944)); } } // namespace l2cap } // namespace bluetooth
system/gd/packet/parser/size.h +2 −1 Original line number Diff line number Diff line Loading @@ -79,7 +79,8 @@ class Size { } int bytes() const { return bits_ / 8; // Round up to the nearest byte return (bits_ + 7) / 8; } Size operator+(int rhs) { Loading
system/gd/packet/parser/struct_def.cc +17 −6 Original line number Diff line number Diff line Loading @@ -89,18 +89,29 @@ void StructDef::GenParse(std::ostream& s) const { s << "{ return struct_begin_it.Subrange(0,0);}"; } Size total_bits{0}; for (const auto& field : fields_) { if (field->GetFieldType() != ReservedField::kFieldType && field->GetFieldType() != BodyField::kFieldType && field->GetFieldType() != FixedScalarField::kFieldType && field->GetFieldType() != SizeField::kFieldType && field->GetFieldType() != ChecksumStartField::kFieldType && field->GetFieldType() != ChecksumField::kFieldType && field->GetFieldType() != CountField::kFieldType) { total_bits += field->GetSize().bits(); } } s << "{"; s << "if (to_bound.NumBytesRemaining() < " << field->GetSize().bytes() << ")"; s << "if (to_bound.NumBytesRemaining() < " << total_bits.bytes() << ")"; if (!fields_.HasBody()) { s << "{ return to_bound.Subrange(to_bound.NumBytesRemaining(),0);}"; } else { s << "{ return {};}"; } s << "}"; for (const auto& field : fields_) { if (field->GetFieldType() != ReservedField::kFieldType && field->GetFieldType() != BodyField::kFieldType && field->GetFieldType() != FixedScalarField::kFieldType && field->GetFieldType() != SizeField::kFieldType && field->GetFieldType() != ChecksumStartField::kFieldType && field->GetFieldType() != ChecksumField::kFieldType && field->GetFieldType() != CountField::kFieldType) { s << "{"; int num_leading_bits = field->GenBounds(s, GetStructOffsetForField(field->GetName()), Size(), field->GetStructSize()); s << "auto " << field->GetName() << "_ptr = &to_fill->" << field->GetName() << "_;"; Loading
system/gd/packet/parser/test/generated_packet_test.cc +26 −4 Original line number Diff line number Diff line Loading @@ -1667,15 +1667,15 @@ TEST(GeneratedPacketTest, testOneGenericStructFourArray) { parent_vector[3] = std::move(fbs); std::array<std::unique_ptr<UnusedParentStruct>, 4> vector_copy; size_t i = 0; size_t index = 0; for (auto& s : parent_vector) { if (s->struct_type_ == StructType::TWO_BYTE) { vector_copy[i] = std::make_unique<TwoByteStruct>(*(TwoByteStruct*)s.get()); vector_copy[index] = std::make_unique<TwoByteStruct>(*(TwoByteStruct*)s.get()); } if (s->struct_type_ == StructType::FOUR_BYTE) { vector_copy[i] = std::make_unique<FourByteStruct>(*(FourByteStruct*)s.get()); vector_copy[index] = std::make_unique<FourByteStruct>(*(FourByteStruct*)s.get()); } i++; index++; } auto packet = OneGenericStructFourArrayBuilder::Create(std::move(parent_vector)); Loading Loading @@ -1877,6 +1877,28 @@ TEST(GeneratedPacketTest, testByteSizedFields) { DEFINE_AND_INSTANTIATE_ByteSizedFieldsReflectionTest(byte_sized); TEST(GeneratedPacketTest, testOneGenericStructArrayNoZeroEmpty) { auto too_few_bytes = std::make_shared<std::vector<uint8_t>>(0); auto view = OneGenericStructArrayNoZeroView::Create(too_few_bytes); for (size_t i = 0; i < 10; i++) { if (view.IsValid()) { view.GetAnArray().size(); } too_few_bytes->push_back(0); view = OneGenericStructArrayNoZeroView::Create(too_few_bytes); } std::vector<uint8_t> a_two_byte_struct = { static_cast<uint8_t>(StructTypeNoZero::TWO_BYTE), 0x01, 0x02, }; too_few_bytes = std::make_shared<std::vector<uint8_t>>(a_two_byte_struct); view = OneGenericStructArrayNoZeroView::Create(too_few_bytes); ASSERT(view.IsValid()); ASSERT_EQ(1, view.GetAnArray().size()); } } // namespace parser } // namespace packet } // namespace bluetooth
system/gd/packet/parser/test/test_packets.pdl +35 −0 Original line number Diff line number Diff line Loading @@ -405,3 +405,38 @@ packet ByteSizedFields { seven : 56, eight : 64, } enum StructTypeNoZero : 4 { TWO_BYTE = 0x02, FOUR_BYTE = 0x04, AT_LEAST_FOUR_BYTE = 0x05, } struct UnusedParentStructNoZero { struct_type : StructTypeNoZero, _reserved_ : 4, length : 8, _body_, } struct TwoByteStructNoZero : UnusedParentStructNoZero (struct_type = TWO_BYTE, length = 2) { two_bytes : 16, } struct FourByteStructNoZero : UnusedParentStructNoZero (struct_type = FOUR_BYTE, length = 4) { four_bytes : 32, } struct AtLeastFourByteStructNoZero : UnusedParentStructNoZero (struct_type = AT_LEAST_FOUR_BYTE) { four_bytes : 32, struct_type : StructTypeNoZero, _body_, } struct EightByteStructNoZero : AtLeastFourByteStructNoZero (struct_type = FOUR_BYTE, length = 9) { four_bytes : 32, } packet OneGenericStructArrayNoZero { an_array : UnusedParentStructNoZero[], }