From e5717d1ba2184eb6e38b4e2a9d29dc4704aeef30 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Sun, 8 Jan 2023 11:31:36 +0000 Subject: [PATCH] Range-check record lengths when deserialising games "1999999999999999999999999999999999999999999999999999" as a record length should lead to an error, not a buffer overrun. (fun fact that was less obvious to me than it should have been: very large powers of ten are multiples of large powers of two, so that number is -1 mod 2^32) This bug can be demonstrated by building any puzzle with AddressSanitizer and then loading this save file: SAVEFILE:41:Simon Tatham's Portable Puzzle Collection VERSION :1999999999999999999999999999999999999999999999999999:1 --- midend.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/midend.c b/midend.c index 67606bb..27c015b 100644 --- a/midend.c +++ b/midend.c @@ -2310,7 +2310,7 @@ static const char *midend_deserialise_internal( if (c == ':') { break; - } else if (c >= '0' && c <= '9') { + } else if (c >= '0' && c <= '9' && len < (INT_MAX - 10) / 10) { len = (len * 10) + (c - '0'); } else { if (started) @@ -2704,7 +2704,7 @@ const char *identify_game(char **name, if (c == ':') { break; - } else if (c >= '0' && c <= '9') { + } else if (c >= '0' && c <= '9' && len < (INT_MAX - 10) / 10) { len = (len * 10) + (c - '0'); } else { if (started)