File CVE-2024-33870.patch of Package ghostscript.38120

--- base/gpmisc.c.bsc1219357.patched.CVE-2023-36664.patched	2024-06-28 14:30:53.255175806 +0200
+++ base/gpmisc.c	2024-06-28 14:37:32.710786933 +0200
@@ -1012,7 +1012,7 @@ gp_validate_path_len(const gs_memory_t *
                  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();
@@ -1065,8 +1065,10 @@ gp_validate_path_len(const gs_memory_t *
             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) {
@@ -1094,9 +1096,34 @@ gp_validate_path_len(const gs_memory_t *
             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) {
@@ -1106,6 +1133,7 @@ gp_validate_path_len(const gs_memory_t *
         break;
     }
 
+exit:
     gs_free_object(mem->thread_safe_memory, bufferfull, "gp_validate_path");
 #ifdef EACCES
     if (code == gs_error_invalidfileaccess)
openSUSE Build Service is sponsored by