Skip to content

Commit dff6ea5

Browse files
committed
import fuchsia: check bounds to handle truncated traces
the last record might be partially written so it's important to check bounds and dump the last record if that happens.
1 parent 747a3cd commit dff6ea5

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

‎import-fuchsia/src/import-fuchsia.cpp‎

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <cstdint>
44
#include <exception>
55
#include <ostream>
6+
#include <utility>
67
#include <vector>
78
#ifdef _WIN32
89
#include <windows.h>
@@ -70,7 +71,6 @@ struct PidTidEncoder {
7071
// A span into the main buffer
7172
struct Record {
7273
const uint64_t *p;
73-
;
7474
uint16_t len_word;
7575
uint64_t header;
7676
};
@@ -171,13 +171,26 @@ std::vector<uint8_t> read_input(const char *input) {
171171
return buf;
172172
}
173173

174-
// read next record starting at `offset`
175-
Record read_next_record(std::vector<uint8_t> const &input, size_t &offset) {
174+
// read next record starting at `offset`. Returns
175+
// either `(ok, r)` for an in-bound record, or `(false, …)` otherwise.
176+
std::pair<bool, Record> read_next_record(std::vector<uint8_t> const &input, size_t &offset) {
177+
178+
// bound check
179+
#define CHECK_BOUND(n) if ((n) > input.size()) { \
180+
fprintf(stderr, "warning: invalid record at offset %" PRIu64 "\n", offset); \
181+
return std::make_pair(false,Record{}); \
182+
}
183+
184+
CHECK_BOUND(offset+8);
185+
176186
uint64_t header = *((uint64_t *)&input[offset]);
177187
uint16_t len_word = (header >> 4) & 0xfff;
178-
Record sp{(uint64_t *)&input[offset], len_word, header};
188+
189+
CHECK_BOUND(offset + 8*len_word);
190+
191+
Record r{(uint64_t *)&input[offset], len_word, header};
179192
offset += 8 * len_word;
180-
return sp;
193+
return std::make_pair(true, r);
181194
}
182195

183196
// there might be multiple processes so we allocate a pseudo-tid
@@ -398,7 +411,8 @@ int main(int argc, char **argv) {
398411
#define CHECK_INIT() if (!initialized) throw TraceNotInitialized{}
399412

400413
while (offset < buf.size()) {
401-
Record r = read_next_record(buf, offset);
414+
auto [ok, r] = read_next_record(buf, offset);
415+
if (!ok) break;
402416
n_records++;
403417

404418
uint8_t ty = r.header & 0xf;

0 commit comments

Comments
 (0)