From ec55cbc879b9874169cb9521fe446850ba969ce8 Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Thu, 13 Nov 2025 14:20:19 -0600 Subject: [PATCH] wuffs: protect against crafted images that cause overflows Fixes #9579 Protect against panics caused by integer overflows by using functions that allow integer overflows to be caught instead of causing a panic. Also protect against DOS from images that might not cause an overflow but do consume an absurd amount of memory by limiting images to a maximum size of 4GiB (which is the maximum size of `image-storage-limit`). --- pkg/wuffs/src/error.zig | 2 +- pkg/wuffs/src/jpeg.zig | 20 +++++++++++++++++++- pkg/wuffs/src/main.zig | 4 ++++ pkg/wuffs/src/png.zig | 20 +++++++++++++++++++- pkg/wuffs/src/too_big.jpg | Bin 0 -> 12586488 bytes pkg/wuffs/src/too_big.png | Bin 0 -> 1045503 bytes src/terminal/kitty/graphics_image.zig | 1 + 7 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 pkg/wuffs/src/too_big.jpg create mode 100644 pkg/wuffs/src/too_big.png diff --git a/pkg/wuffs/src/error.zig b/pkg/wuffs/src/error.zig index c75188718..0be55cf4e 100644 --- a/pkg/wuffs/src/error.zig +++ b/pkg/wuffs/src/error.zig @@ -2,7 +2,7 @@ const std = @import("std"); const c = @import("c.zig").c; -pub const Error = std.mem.Allocator.Error || error{WuffsError}; +pub const Error = std.mem.Allocator.Error || error{ WuffsError, Overflow }; pub fn check(log: anytype, status: *const c.struct_wuffs_base__status__struct) error{WuffsError}!void { if (!c.wuffs_base__status__is_ok(status)) { diff --git a/pkg/wuffs/src/jpeg.zig b/pkg/wuffs/src/jpeg.zig index 700ba01b9..69d91c8a9 100644 --- a/pkg/wuffs/src/jpeg.zig +++ b/pkg/wuffs/src/jpeg.zig @@ -4,6 +4,8 @@ const c = @import("c.zig").c; const Error = @import("error.zig").Error; const check = @import("error.zig").check; const ImageData = @import("main.zig").ImageData; +const maximum_image_size = @import("main.zig").maximum_image_size; +const mul = std.math.mul; const log = std.log.scoped(.wuffs_jpeg); @@ -61,9 +63,20 @@ pub fn decode(alloc: Allocator, data: []const u8) Error!ImageData { height, ); + const size: usize = try mul( + usize, + try mul(usize, width, height), + @sizeOf(c.wuffs_base__color_u32_argb_premul), + ); + + if (size > maximum_image_size) { + log.warn("image size {d} is larger than the maximum allowed ({d})", .{ size, maximum_image_size }); + return error.Overflow; + } + const destination = try alloc.alloc( u8, - width * height * @sizeOf(c.wuffs_base__color_u32_argb_premul), + size, ); errdefer alloc.free(destination); @@ -131,3 +144,8 @@ test "jpeg_decode_FFFFFF" { try std.testing.expectEqual(1, data.height); try std.testing.expectEqualSlices(u8, &.{ 255, 255, 255, 255 }, data.data); } + +test "jpeg: too big" { + const data = decode(std.testing.allocator, @embedFile("too_big.jpg")); + try std.testing.expectError(error.Overflow, data); +} diff --git a/pkg/wuffs/src/main.zig b/pkg/wuffs/src/main.zig index 89f3c008c..207d83f9a 100644 --- a/pkg/wuffs/src/main.zig +++ b/pkg/wuffs/src/main.zig @@ -5,6 +5,10 @@ pub const jpeg = @import("jpeg.zig"); pub const swizzle = @import("swizzle.zig"); pub const Error = @import("error.zig").Error; +/// The maximum image size, based on the 4G limit of Ghostty's +/// `image-storage-limit` config. +pub const maximum_image_size = 4 * 1024 * 1024 * 1024; + pub const ImageData = struct { width: u32, height: u32, diff --git a/pkg/wuffs/src/png.zig b/pkg/wuffs/src/png.zig index d79ae5b56..57a0e63bb 100644 --- a/pkg/wuffs/src/png.zig +++ b/pkg/wuffs/src/png.zig @@ -4,6 +4,8 @@ const c = @import("c.zig").c; const Error = @import("error.zig").Error; const check = @import("error.zig").check; const ImageData = @import("main.zig").ImageData; +const maximum_image_size = @import("main.zig").maximum_image_size; +const mul = std.math.mul; const log = std.log.scoped(.wuffs_png); @@ -61,9 +63,20 @@ pub fn decode(alloc: Allocator, data: []const u8) Error!ImageData { height, ); + const size: usize = try mul( + usize, + try mul(usize, width, height), + @sizeOf(c.wuffs_base__color_u32_argb_premul), + ); + + if (size > maximum_image_size) { + log.warn("image size {d} is larger than the maximum allowed ({d})", .{ size, maximum_image_size }); + return error.Overflow; + } + const destination = try alloc.alloc( u8, - width * height * @sizeOf(c.wuffs_base__color_u32_argb_premul), + size, ); errdefer alloc.free(destination); @@ -131,3 +144,8 @@ test "png_decode_FFFFFF" { try std.testing.expectEqual(1, data.height); try std.testing.expectEqualSlices(u8, &.{ 255, 255, 255, 255 }, data.data); } + +test "png: too big" { + const data = decode(std.testing.allocator, @embedFile("too_big.png")); + try std.testing.expectError(error.Overflow, data); +} diff --git a/pkg/wuffs/src/too_big.jpg b/pkg/wuffs/src/too_big.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d7ebf7dbb0d37efdabdad9bc6fdb8443ef91a972 GIT binary patch literal 12586488 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 return error.InvalidData, error.OutOfMemory => return error.OutOfMemory, + error.Overflow => return error.InvalidData, }; defer alloc.free(result.data);