Skip to content

Commit 976a3c3

Browse files
committed
libxdk: added boundary checks for seeking
1 parent c2ddab2 commit 976a3c3

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

libxdk/target/BinaryReader.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ void BinaryReader::SeekToItem(uint64_t seeklist_offset, uint64_t item_idx) {
6666
throw ExpKitError("Seeking is already in progress. Call EndSeek() first.");
6767

6868
seek_origin_offset_ = offset_;
69-
offset_ = seeklist_offset;
69+
SeekTo(seeklist_offset);
7070
auto value = ReadUInt();
7171
auto offset_size = (value & 0x3) + 1;
7272
auto item_count = value >> 2;
@@ -78,12 +78,12 @@ void BinaryReader::SeekToItem(uint64_t seeklist_offset, uint64_t item_idx) {
7878
auto hdr_offset = offset_;
7979
uint64_t item_offset = 0;
8080
if (item_idx != 0) {
81-
offset_ += offset_size * (item_idx - 1);
81+
Skip(offset_size * (item_idx - 1));
8282
item_offset = Uint(offset_size);
8383
}
8484

85-
// skip the seek list
86-
offset_ = hdr_offset + offset_size * item_count + item_offset;
85+
// skip the remaining seek list and jump to the item
86+
Skip((item_count - item_idx) * offset_size + item_offset);
8787
DebugLog(
8888
"SeekToItem(): seeklist_offset=%u, item_idx=%u, offset_size=%u, "
8989
"item_count=%u, item_offset=%u, new offset=%u",
@@ -97,7 +97,7 @@ uint64_t BinaryReader::SeekableListCount() {
9797
auto offset_size = 1 << (hdr & 0x3); // 0=u1, 1=u2, 2=u4, 3=u8
9898
auto item_count = hdr >> 2;
9999
// skip the seek list
100-
offset_ += offset_size * item_count;
100+
Skip(offset_size * item_count);
101101
return item_count;
102102
}
103103

@@ -157,6 +157,11 @@ uint16_t BinaryReader::ReadU16() { return *(uint16_t*)Read(2); }
157157

158158
uint8_t BinaryReader::ReadU8() { return *(uint8_t*)Read(1); }
159159

160+
void BinaryReader::Skip(uint64_t len) {
161+
SizeCheck(len);
162+
offset_ += len;
163+
}
164+
160165
uint8_t* BinaryReader::Read(uint16_t len) {
161166
SizeCheck(len);
162167
uint8_t* ptr = &data_.data()[offset_];
@@ -171,6 +176,14 @@ void BinaryReader::SizeCheck(uint64_t len) {
171176
offset_, len, EndOffset());
172177
}
173178

179+
void BinaryReader::SeekTo(uint64_t offset) {
180+
if (offset >= EndOffset())
181+
throw ExpKitError(
182+
"tried to read seek outside of the buffer: from_offset=%lu, to_offset=%lu, struct_end=%lu",
183+
offset_, offset, EndOffset());
184+
offset_ = offset;
185+
}
186+
174187
uint64_t BinaryReader::RemainingBytes() { return EndOffset() - offset_; }
175188

176189
uint64_t BinaryReader::EndOffset() {

libxdk/target/BinaryReader.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,20 @@ class BinaryReader {
4646
*/
4747
void SizeCheck(uint64_t len);
4848

49+
/**
50+
* @brief Skip len amount of bytes.
51+
* @param len The number of bytes to skip.
52+
* @throws ExpKitError if there are not enough remaining bytes.
53+
*/
54+
void Skip(uint64_t len);
55+
56+
/**
57+
* @brief Seek to offset.
58+
* @param offset The offset within the file to seek.
59+
* @throws ExpKitError if the offset is out-of-bounds.
60+
*/
61+
void SeekTo(uint64_t offset);
62+
4963
/**
5064
* @brief Reads a block of raw bytes from the buffer.
5165
* @param len The number of bytes to read.

libxdk/target/KxdbParser.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,12 @@ std::vector<Target> KxdbParser::ParseTargets(
9292
if (offset_targets_ == 0) ParseHeader();
9393

9494
std::vector<Target> result;
95-
offset_ = offset_targets_;
95+
SeekTo(offset_targets_);
9696
auto num_targets = SeekableListCount(); // by_version
9797
auto offsets = SeekableListOffsets();
98-
DebugLog("ParseTarget(): offset = 0x%x, num_targets=%u, offset[0] = 0x%x", offset_targets_, num_targets, offsets[0]);
98+
DebugLog("ParseTarget(): offset = 0x%x, num_targets=%u", offset_targets_, num_targets);
9999
for (uint32_t i_target = 0; i_target < num_targets; i_target++) {
100-
offset_ = offsets[i_target];
100+
SeekTo(offsets.at(i_target));
101101
const char* t_distro = ZStr();
102102
const char* t_release = ZStr();
103103
const char* t_version = ZStr();
@@ -293,7 +293,7 @@ void KxdbParser::ParseRopActionsHeader() {
293293
DebugLog("rop_action[%d], num_args = %d, desc = '%s'", i, num_args, desc);
294294

295295
RopActionMeta ra(desc);
296-
for (int j = 0; j < num_args; j++) {
296+
for (uint64_t j = 0; j < num_args; j++) {
297297
auto arg_name = ZStr();
298298
auto flags = ReadU8();
299299
bool required = (flags & 0x1) == 0x1;

0 commit comments

Comments
 (0)