diff options
author | Yabin Cui <yabinc@google.com> | 2022-12-12 12:03:11 -0800 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2022-12-12 12:09:28 -0800 |
commit | a9734e3ac68b6a99de69db94b3206ff24f7a5a08 (patch) | |
tree | 71652837dec22ecb69d4940631b7eefda6b17b1e | |
parent | 95f0a957e79e87704ef893e5a7846d844d88c98d (diff) | |
download | extras-a9734e3ac68b6a99de69db94b3206ff24f7a5a08.tar.gz |
simpleperf: fix ReadCmdlineFeature for fuzzer.
Also remove other uses of MoveFromBinaryFormat() in
record_file_reader.cpp.
Bug: 258284687
Test: run simpleperf_unit_test
Change-Id: I12804355afd3f39c1d2ff8dd63391219bd9424a8
-rw-r--r-- | simpleperf/record_file_reader.cpp | 54 | ||||
-rw-r--r-- | simpleperf/utils.h | 6 |
2 files changed, 37 insertions, 23 deletions
diff --git a/simpleperf/record_file_reader.cpp b/simpleperf/record_file_reader.cpp index c70c0dcb..2dbc378a 100644 --- a/simpleperf/record_file_reader.cpp +++ b/simpleperf/record_file_reader.cpp @@ -454,22 +454,25 @@ bool RecordFileReader::ReadFeatureSection(int feature, std::string* data) { std::vector<std::string> RecordFileReader::ReadCmdlineFeature() { std::vector<char> buf; if (!ReadFeatureSection(FEAT_CMDLINE, &buf)) { - return std::vector<std::string>(); + return {}; } - const char* p = buf.data(); - const char* end = buf.data() + buf.size(); + BinaryReader reader(buf.data(), buf.size()); std::vector<std::string> cmdline; - uint32_t arg_count; - MoveFromBinaryFormat(arg_count, p); - CHECK_LE(p, end); - for (size_t i = 0; i < arg_count; ++i) { - uint32_t len; - MoveFromBinaryFormat(len, p); - CHECK_LE(p + len, end); - cmdline.push_back(p); - p += len; + + uint32_t arg_count = 0; + reader.Read(arg_count); + for (size_t i = 0; i < arg_count && !reader.error; ++i) { + uint32_t aligned_len; + reader.Read(aligned_len); + cmdline.emplace_back(reader.ReadString()); + uint32_t len = cmdline.back().size() + 1; + if (aligned_len != Align(len, 64)) { + reader.error = true; + break; + } + reader.Move(aligned_len - len); } - return cmdline; + return reader.error ? std::vector<std::string>() : cmdline; } std::vector<BuildIdRecord> RecordFileReader::ReadBuildIdFeature() { @@ -518,22 +521,27 @@ std::vector<uint64_t> RecordFileReader::ReadAuxTraceFeature() { if (!ReadFeatureSection(FEAT_AUXTRACE, &buf)) { return {}; } - std::vector<uint64_t> auxtrace_offset; - const char* p = buf.data(); - const char* end = buf.data() + buf.size(); - if (buf.size() / sizeof(uint64_t) % 2 == 1) { + BinaryReader reader(buf.data(), buf.size()); + if (reader.LeftSize() % sizeof(uint64_t) != 0) { + return {}; + } + if (reader.LeftSize() / sizeof(uint64_t) % 2 == 1) { // Recording files generated by linux perf contain an extra uint64 field. Skip it here. - p += sizeof(uint64_t); + reader.Move(sizeof(uint64_t)); } - while (p < end) { + + std::vector<uint64_t> auxtrace_offset; + while (!reader.error && reader.LeftSize() > 0u) { uint64_t offset; uint64_t size; - MoveFromBinaryFormat(offset, p); + reader.Read(offset); + reader.Read(size); auxtrace_offset.push_back(offset); - MoveFromBinaryFormat(size, p); - CHECK_EQ(size, AuxTraceRecord::Size()); + if (size != AuxTraceRecord::Size()) { + reader.error = true; + } } - return auxtrace_offset; + return reader.error ? std::vector<uint64_t>() : auxtrace_offset; } bool RecordFileReader::ReadFileFeature(size_t& read_pos, FileFeature* file) { diff --git a/simpleperf/utils.h b/simpleperf/utils.h index a9f8aa6d..ebc96068 100644 --- a/simpleperf/utils.h +++ b/simpleperf/utils.h @@ -166,6 +166,12 @@ struct BinaryReader { return true; } + void Move(size_t size) { + if (CheckLeftSize(size)) { + head += size; + } + } + template <class T> void Read(T& data) { static_assert(std::is_standard_layout<T>::value, "not standard layout"); |