diff options
author | Googler <noreply@google.com> | 2023-03-08 16:15:33 -0800 |
---|---|---|
committer | shantuo <sturbo89@gmail.com> | 2023-03-29 13:41:38 -0700 |
commit | 7b5556657d34dd206a6380df6bc1cdf08c1a7faa (patch) | |
tree | 67a8344899bc969c7fb14602ddb7f185b2dccbb0 | |
parent | 256bfa5d790cc0964916f07fa0b8af962c02d01a (diff) | |
download | perf_data_converter-7b5556657d34dd206a6380df6bc1cdf08c1a7faa.tar.gz |
Check the size of build ID before HexString conversion in mmap2 de/serialization
PiperOrigin-RevId: 515170579
-rw-r--r-- | src/quipper/perf_serializer.cc | 12 | ||||
-rw-r--r-- | src/quipper/perf_serializer_test.cc | 45 |
2 files changed, 52 insertions, 5 deletions
diff --git a/src/quipper/perf_serializer.cc b/src/quipper/perf_serializer.cc index ff659db..f1f0331 100644 --- a/src/quipper/perf_serializer.cc +++ b/src/quipper/perf_serializer.cc @@ -705,6 +705,12 @@ bool PerfSerializer::SerializeMMap2Event( sample->set_len(mmap.len); sample->set_pgoff(mmap.pgoff); if (event.header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID) { + if (mmap.build_id_size > sizeof(mmap.build_id)) { + LOG(ERROR) + << "Invalid build_id_size, possibly data corruption: build_id_size = " + << mmap.build_id_size; + return false; + } sample->set_build_id(RawDataToHexString(mmap.build_id, mmap.build_id_size)); } else { sample->set_maj(mmap.maj); @@ -735,13 +741,15 @@ bool PerfSerializer::DeserializeMMap2Event( mmap.pgoff = sample.pgoff(); if (sample.has_build_id()) { uint8_t bytes[kBuildIDArraySize]; - if (HexStringToRawData(sample.build_id(), bytes, sizeof(bytes))) { + if (sample.build_id().size() % kHexCharsPerByte == 0 && + sample.build_id().size() / kHexCharsPerByte <= sizeof(bytes) && + HexStringToRawData(sample.build_id(), bytes, sizeof(bytes))) { mmap.build_id_size = sample.build_id().size() / kHexCharsPerByte; memset(mmap.build_id, 0, sizeof(mmap.build_id)); memcpy(mmap.build_id, bytes, mmap.build_id_size); } else { LOG(ERROR) << "Failed to convert build_id=" << sample.build_id() - << " into bytes."; + << " (size=" << sample.build_id().size() << ") into bytes."; return false; } } else { diff --git a/src/quipper/perf_serializer_test.cc b/src/quipper/perf_serializer_test.cc index 3a37a9d..d1892b9 100644 --- a/src/quipper/perf_serializer_test.cc +++ b/src/quipper/perf_serializer_test.cc @@ -703,9 +703,48 @@ TEST(PerfSerializerTest, SerializesAndDeserializesMmapEvents) { PerfDataProto perf_data_proto_2; DeserializeAndSerialize(perf_data_proto, &perf_data_proto_2); - std::string difference; - bool matches = EqualsProto(perf_data_proto_2, perf_data_proto, &difference); - EXPECT_FALSE(matches) << difference; + EXPECT_NE(perf_data_proto_2.events().size(), + perf_data_proto.events().size()); + } + + { + // Deserialization should fail when the build ID is not a complete hex str. + // E.g. "abc", where "ab" is a byte, but that single "c" is not. + perf_data_proto.mutable_events(2)->mutable_mmap_event()->set_build_id( + "abc"); + PerfDataProto perf_data_proto_2; + DeserializeAndSerialize(perf_data_proto, &perf_data_proto_2); + + EXPECT_NE(perf_data_proto_2.events().size(), + perf_data_proto.events().size()); + } + + { + // Deserialization should fail when the build ID is larger than the + // maximum value of the build ID field of mmap2 perf event. + // https://source.corp.google.com/piper///depot/google3/third_party/linux_tools/src/tools/lib/perf/include/perf/event.h;l=39;bpv=1;bpt=0;rcl=483414731 + perf_data_proto.mutable_events(2)->mutable_mmap_event()->set_build_id( + std::string(kMaxBuildIdSize * 2 + 2, 'a')); + PerfDataProto perf_data_proto_2; + DeserializeAndSerialize(perf_data_proto, &perf_data_proto_2); + + EXPECT_NE(perf_data_proto_2.events().size(), + perf_data_proto.events().size()); + } + + { + // Serialization should fail when the build_id_size field is larger than the + // maximum value of the build ID field of mmap2 perf event. + std::vector<u8> build_id = {0x0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xef, 0x0}; + testing::ExampleMmap2Event(1003, 0x2c1000, 0x2000, 0x3000, + "/usr/lib/bar.so", + testing::SampleInfo().Tid(1003)) + .WithMisc(PERF_RECORD_MISC_MMAP_BUILD_ID) + .WithBuildId(build_id.data(), kMaxBuildIdSize + 1) + .WriteTo(&input); + PerfReader reader; + ASSERT_FALSE(reader.ReadFromString(input.str())); } } |