Skip to content

Commit 04b4742

Browse files
committed
std.compress.xz: Avoid possible integer overflow in a few places
Closes ziglang#14500
1 parent d6b430b commit 04b4742

File tree

3 files changed

+23
-3
lines changed

3 files changed

+23
-3
lines changed

lib/std/compress/xz.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ pub fn Decompress(comptime ReaderType: type) type {
118118
var hasher = std.compress.hashedReader(self.in_reader, Crc32.init());
119119
const hashed_reader = hasher.reader();
120120

121-
const backward_size = (try hashed_reader.readIntLittle(u32) + 1) * 4;
121+
const backward_size = (@as(u64, try hashed_reader.readIntLittle(u32)) + 1) * 4;
122122
if (backward_size != index_size)
123123
return error.CorruptInput;
124124

lib/std/compress/xz/block.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ pub fn Decoder(comptime ReaderType: type) type {
9898
var header_hasher = std.compress.hashedReader(block_reader, Crc32.init());
9999
const header_reader = header_hasher.reader();
100100

101-
const header_size = try header_reader.readByte() * 4;
101+
const header_size = @as(u64, try header_reader.readByte()) * 4;
102102
if (header_size == 0)
103103
return error.EndOfStreamWithNoError;
104104

@@ -217,7 +217,7 @@ pub fn Decoder(comptime ReaderType: type) type {
217217
if (status == 1)
218218
try self.accum.reset(self.allocator);
219219

220-
const size = try packed_reader.readIntBig(u16) + 1;
220+
const size = @as(u17, try packed_reader.readIntBig(u16)) + 1;
221221
try self.accum.ensureUnusedCapacity(self.allocator, size);
222222

223223
var i: usize = 0;

lib/std/compress/xz/test.zig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,23 @@ test "unsupported" {
7878
);
7979
}
8080
}
81+
82+
fn testDontPanic(data: []const u8) !void {
83+
const buf = decompress(data) catch |err| switch (err) {
84+
error.OutOfMemory => |e| return e,
85+
else => return,
86+
};
87+
defer testing.allocator.free(buf);
88+
}
89+
90+
test "size fields: integer overflow avoidance" {
91+
// These cases were found via fuzz testing and each previously caused
92+
// an integer overflow when decoding. We just want to ensure they no longer
93+
// cause a panic
94+
const header_size_overflow = "\xfd7zXZ\x00\x00\x01i\"\xde6z";
95+
try testDontPanic(header_size_overflow);
96+
const lzma2_chunk_size_overflow = "\xfd7zXZ\x00\x00\x01i\"\xde6\x02\x00!\x01\x08\x00\x00\x00\xd8\x0f#\x13\x01\xff\xff";
97+
try testDontPanic(lzma2_chunk_size_overflow);
98+
const backward_size_overflow = "\xfd7zXZ\x00\x00\x01i\"\xde6\x00\x00\x00\x00\x1c\xdfD!\x90B\x99\r\x01\x00\x00\xff\xff\x10\x00\x00\x00\x01DD\xff\xff\xff\x01";
99+
try testDontPanic(backward_size_overflow);
100+
}

0 commit comments

Comments
 (0)