Bug 699623 - Incomplete fix for #697178 Allowing -dSAFER bypass
Summary: Incomplete fix for #697178 Allowing -dSAFER bypass
Status: RESOLVED FIXED
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: General (show other bugs)
Version: unspecified
Hardware: PC All
: P4 major
Assignee: Chris Liddell (chrisl)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-08-08 18:36 UTC by amitbl
Modified: 2018-12-18 11:36 UTC (History)
5 users (show)

See Also:
Customer:
Word Size: ---


Attachments
poc (141 bytes, text/plain)
2018-08-08 18:36 UTC, amitbl
Details

Note You need to log in before you can comment on or make changes to this bug.
Description amitbl 2018-08-08 18:36:51 UTC
Created attachment 15447 [details]
poc

I was looking at the fix for #697178 and found out that the applied patch is not entierly fixing the issue.
http://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=6d444c273da5499a4cd72f21cb6d4c9a5256807d
The permission check is being applied only on the filename, ignoring the fact that a previous call to sfopen is being made with the the profile dir as well. (which can be user-controlled with .setuserparams)

    static int
    gsicc_open_search(const char* pname, int namelen, gs_memory_t *mem_gc,
            const char* dirname, int dirlen, stream**strp)
    {
        char *buffer;
        stream* str;
    
        /* Check if we need to prepend the file name  */
        if ( dirname != NULL) {
            /* If this fails, we will still try the file by itself and with
               %rom% since someone may have left a space some of the spaces
               as our defaults, even if they defined the directory to use.
               This will occur only after searching the defined directory.
               A warning is noted.  */
            buffer = (char *) gs_alloc_bytes(mem_gc, namelen + dirlen + 1,
                    "gsicc_open_search");
            if (buffer == NULL)
                return_error(gs_error_VMerror);
            strcpy(buffer, dirname);
            strcat(buffer, pname);
            /* Just to make sure we were null terminated */
            buffer[namelen + dirlen] = '\0';
            str = sfopen(buffer, "r", mem_gc); // << no input validation, user-controllable value
            gs_free_object(mem_gc, buffer, "gsicc_open_search");
            if (str != NULL) {
                *strp = str;
                return 0;
            }
        }
    
        /* First just try it like it is */
        if (gs_check_file_permission(mem_gc, pname, namelen, "r") >= 0) {
            str = sfopen(pname, "r", mem_gc);
            if (str != NULL) {
                *strp = str;
                return 0;
            }
        }

After fully reading the original bug report I've noticed Tavis Ormandy also mentioned this in his last comment (https://bugs.ghostscript.com/show_bug.cgi?id=697178#c7), but for some reason it was left unnoticed.
I'm adding a simple poc very similar to the original, tested on latest ubuntu with their shipped ghostscript package.
In my testing this poc also segfaults the entire process, but I have not investigated this further.
Comment 1 Chris Liddell (chrisl) 2018-08-23 11:46:00 UTC
Fixed in

http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=d224b4abec