aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGoogler <noreply@google.com>2023-03-08 16:15:33 -0800
committershantuo <sturbo89@gmail.com>2023-03-29 13:41:38 -0700
commit7b5556657d34dd206a6380df6bc1cdf08c1a7faa (patch)
tree67a8344899bc969c7fb14602ddb7f185b2dccbb0
parent256bfa5d790cc0964916f07fa0b8af962c02d01a (diff)
downloadperf_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.cc12
-rw-r--r--src/quipper/perf_serializer_test.cc45
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()));
}
}