diff options
author | Zdenek Hutyra <zhutyra@centrum.cz> | 2024-05-27 13:38:36 +0100 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2024-09-18 14:33:12 +0100 |
commit | 1f21a45df0fa3abec4cff12951022b192dda3c00 (patch) | |
tree | 907376b3e6ef02de920a3636d79642b02327a389 | |
parent | c3dbaf8690f681b90a1d219bd94560a9f6336da4 (diff) |
Bug 707793: Check for overflow validating format string
for the output file name
CVE-2024-46953
-rw-r--r-- | base/gsdevice.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/base/gsdevice.c b/base/gsdevice.c index 90e699ab4..49354d833 100644 --- a/base/gsdevice.c +++ b/base/gsdevice.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2023 Artifex Software, Inc. +/* Copyright (C) 2001-2024 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -1070,7 +1070,7 @@ static int gx_parse_output_format(gs_parsed_file_name_t *pfn, const char **pfmt) { bool have_format = false, field; - int width[2], int_width = sizeof(int) * 3, w = 0; + uint width[2], int_width = sizeof(int) * 3, w = 0; uint i; /* Scan the file name for a format string, and validate it if present. */ @@ -1099,6 +1099,8 @@ gx_parse_output_format(gs_parsed_file_name_t *pfn, const char **pfmt) default: /* width (field = 0) and precision (field = 1) */ if (strchr("0123456789", pfn->fname[i])) { width[field] = width[field] * 10 + pfn->fname[i] - '0'; + if (width[field] > max_int) + return_error(gs_error_undefinedfilename); continue; } else if (0 == field && '.' == pfn->fname[i]) { field++; @@ -1127,8 +1129,10 @@ gx_parse_output_format(gs_parsed_file_name_t *pfn, const char **pfmt) /* Calculate a conservative maximum width. */ w = max(width[0], width[1]); w = max(w, int_width) + 5; + if (w > max_int) + return_error(gs_error_undefinedfilename); } - return w; + return (int)w; } /* @@ -1181,10 +1185,15 @@ gx_parse_output_file_name(gs_parsed_file_name_t *pfn, const char **pfmt, if (!pfn->fname) return 0; code = gx_parse_output_format(pfn, pfmt); - if (code < 0) + if (code < 0) { return code; - if (strlen(pfn->iodev->dname) + pfn->len + code >= gp_file_name_sizeof) + } + + if (pfn->len >= gp_file_name_sizeof - strlen(pfn->iodev->dname) || + code >= gp_file_name_sizeof - strlen(pfn->iodev->dname) - pfn->len) { return_error(gs_error_undefinedfilename); + } + return 0; } |