From eaeff56158f064ef4dfd2a9b5d5a6f7645383bf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trung=20L=C3=AA?= <8@tle.id.au> Date: Wed, 4 Feb 2026 10:30:25 +1100 Subject: [PATCH] Fix VLA stack overflow risk in flip_exists (gfx.c) Replace variable-length array with heap allocation and add bounds checking to prevent stack overflow from malicious depth values. --- tools/gfx.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/gfx.c b/tools/gfx.c index c8f0b03f4..3f5ba8878 100644 --- a/tools/gfx.c +++ b/tools/gfx.c @@ -206,15 +206,23 @@ const uint8_t flipped[256] = { 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff }; +// Maximum tile size to prevent excessive memory allocation (depth 255 * 16 = 4080) +#define MAX_TILE_SIZE 4096 + bool flip_exists(const uint8_t *tile, const uint8_t *tiles, int tile_size, int num_tiles, bool xflip, bool yflip) { - uint8_t flip[tile_size]; // VLA + if (tile_size <= 0 || tile_size > MAX_TILE_SIZE) { + error_exit("Invalid tile size: %d\n", tile_size); + } + uint8_t *flip = xmalloc(tile_size); memset(flip, 0, tile_size); int half_size = tile_size / 2; for (int i = 0; i < tile_size; i++) { int j = yflip ? (options.interleave && i < half_size ? half_size : tile_size) - 1 - (i ^ 1) : i; flip[j] = xflip ? flipped[tile[i]] : tile[i]; } - return tile_exists(flip, tiles, tile_size, num_tiles); + bool result = tile_exists(flip, tiles, tile_size, num_tiles); + free(flip); + return result; } void remove_flip(struct Graphic *graphic, bool xflip, bool yflip) {