diff --git a/base/gpmisc.c b/base/gpmisc.c index f9a9230..2b43f89 100644 --- a/base/gpmisc.c +++ b/base/gpmisc.c @@ -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(); @@ -1095,8 +1095,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) { @@ -1131,9 +1133,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) { @@ -1152,6 +1179,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)