summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2022-12-12 12:03:11 -0800
committerYabin Cui <yabinc@google.com>2022-12-12 12:09:28 -0800
commita9734e3ac68b6a99de69db94b3206ff24f7a5a08 (patch)
tree71652837dec22ecb69d4940631b7eefda6b17b1e
parent95f0a957e79e87704ef893e5a7846d844d88c98d (diff)
downloadextras-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.cpp54
-rw-r--r--simpleperf/utils.h6
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");