From 79aef19c685984dc3da2dc090450407d9fbcff80 Mon Sep 17 00:00:00 2001 From: Ken Sharp Date: Tue, 26 Mar 2024 12:00:14 +0000 Subject: [PATCH] Bug #707686 See bug thread for details In addition to the noted bug; an error path (return from gp_file_name_reduce not successful) could elad to a memory leak as we did not free 'bufferfull'. Fix that too. This addresses CVE-2024-33870 --- base/gpmisc.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/base/gpmisc.c b/base/gpmisc.c index 2b0064bea..c4a69b03a 100644 --- a/base/gpmisc.c +++ b/base/gpmisc.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 @@ -1042,7 +1042,7 @@ gp_validate_path_len(const gs_memory_t *mem, const uint len, const char *mode) { - char *buffer, *bufferfull; + char *buffer, *bufferfull = NULL; uint rlen; int code = 0; const char *cdirstr = gp_file_name_current(); @@ -1096,8 +1096,10 @@ gp_validate_path_len(const gs_memory_t *mem, return gs_error_VMerror; buffer = bufferfull + prefix_len; - if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success) - return gs_error_invalidfileaccess; + if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success) { + code = gs_note_error(gs_error_invalidfileaccess); + goto exit; + } buffer[rlen] = 0; } while (1) { @@ -1132,9 +1134,34 @@ gp_validate_path_len(const gs_memory_t *mem, code = gs_note_error(gs_error_invalidfileaccess); } if (code < 0 && prefix_len > 0 && buffer > bufferfull) { + uint newlen = rlen + cdirstrl + dirsepstrl; + char *newbuffer; + int code; + buffer = bufferfull; memcpy(buffer, cdirstr, cdirstrl); memcpy(buffer + cdirstrl, dirsepstr, dirsepstrl); + + /* We've prepended a './' or similar for the current working directory. We need + * to execute file_name_reduce on that, to eliminate any '../' or similar from + * the (new) full path. + */ + newbuffer = (char *)gs_alloc_bytes(mem->thread_safe_memory, newlen + 1, "gp_validate_path"); + if (newbuffer == NULL) { + code = gs_note_error(gs_error_VMerror); + goto exit; + } + + memcpy(newbuffer, buffer, rlen + cdirstrl + dirsepstrl); + newbuffer[newlen] = 0x00; + + code = gp_file_name_reduce(newbuffer, (uint)newlen, buffer, &newlen); + gs_free_object(mem->thread_safe_memory, newbuffer, "gp_validate_path"); + if (code != gp_combine_success) { + code = gs_note_error(gs_error_invalidfileaccess); + goto exit; + } + continue; } else if (code < 0 && cdirstrl > 0 && prefix_len == 0 && buffer == bufferfull) { @@ -1153,6 +1180,7 @@ gp_validate_path_len(const gs_memory_t *mem, gs_path_control_flag_is_scratch_file); } +exit: gs_free_object(mem->thread_safe_memory, bufferfull, "gp_validate_path"); #ifdef EACCES if (code == gs_error_invalidfileaccess) -- 2.45.2