diff --git a/lib/std/tar.zig b/lib/std/tar.zig index 6c67600731..437a3b736f 100644 --- a/lib/std/tar.zig +++ b/lib/std/tar.zig @@ -376,7 +376,7 @@ fn Iterator(comptime ReaderType: type) type { self.file.link_name = try attr.value(&self.link_name_buffer); }, .size => { - var buf: [64]u8 = undefined; + var buf: [pax_max_size_attr_len]u8 = undefined; self.file.size = try std.fmt.parseInt(u64, try attr.value(&buf), 10); }, } @@ -430,6 +430,9 @@ const PaxAttributeKind = enum { size, }; +// maxInt(u64) has 20 chars, base 10 in practice we got 24 chars +const pax_max_size_attr_len = 64; + fn PaxIterator(comptime ReaderType: type) type { return struct { size: usize, // cumulative size of all pax attributes @@ -486,6 +489,9 @@ fn PaxIterator(comptime ReaderType: type) type { try validateAttributeEnding(self.reader); continue; }; + if (kind == .size and value_len > pax_max_size_attr_len) { + return error.PaxSizeAttrOverflow; + } return Attribute{ .kind = kind, .len = value_len, diff --git a/lib/std/tar/test.zig b/lib/std/tar/test.zig index f77b8a778a..5bc7638195 100644 --- a/lib/std/tar/test.zig +++ b/lib/std/tar/test.zig @@ -317,6 +317,10 @@ test "tar run Go test cases" { .data = @embedFile("testdata/fuzz1.tar"), .err = error.TarCorruptInput, }, + .{ + .data = @embedFile("testdata/fuzz2.tar"), + .err = error.PaxSizeAttrOverflow, + }, }; for (cases) |case| { diff --git a/lib/std/tar/testdata/fuzz2.tar b/lib/std/tar/testdata/fuzz2.tar new file mode 100644 index 0000000000..ef86cfe386 Binary files /dev/null and b/lib/std/tar/testdata/fuzz2.tar differ