summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2022-12-13 18:35:16 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2022-12-13 18:35:16 +0000
commite12362dad5be8bb95d5d8c4bac09c3aa1a21873c (patch)
treed47ef59f44f3564ef5b7f697e53f2700c3fbee50
parent33c211227b381e59590bf3bea89057942b62e102 (diff)
parenta9734e3ac68b6a99de69db94b3206ff24f7a5a08 (diff)
downloadextras-e12362dad5be8bb95d5d8c4bac09c3aa1a21873c.tar.gz
Merge "simpleperf: fix ReadCmdlineFeature for fuzzer."
-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");