diff options
author | Chris Liddell <chris.liddell@artifex.com> | 2017-02-14 10:22:46 +0000 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2017-02-14 12:27:01 +0000 |
commit | b3acfdeaf1eb63a07e8169ea4c30ace7522054bc (patch) | |
tree | c01a3f3ff6f0a3bc8e2825804b8a7363e6129639 /psi/zfile.c | |
parent | 3d14e0b20dfdc05cda60f7a9a4c78e9d3ee206e2 (diff) | |
download | ghostpdl-b3acfdeaf1eb63a07e8169ea4c30ace7522054bc.tar.gz |
Yet more SAFER problems with .libfile
With the change to ensure we only apply SAFER permissions to real file system
operations (so only on '%os%' and not on other PS '%<device>%' devices), the
.libfile call was dropping through without being restricted.
This changes the .libfile code to call the permissions checking function
properly.
Diffstat (limited to 'psi/zfile.c')
-rw-r--r-- | psi/zfile.c | 60 |
1 files changed, 31 insertions, 29 deletions
diff --git a/psi/zfile.c b/psi/zfile.c index 97dda1b60..a5e75b0dd 100644 --- a/psi/zfile.c +++ b/psi/zfile.c @@ -986,17 +986,6 @@ make_stream_file(ref * pfile, stream * s, const char *access) } } -static int -check_file_permissions_aux(i_ctx_t *i_ctx_p, char *fname, uint flen) -{ /* i_ctx_p is NULL running init files. */ - /* fname must be reduced. */ - if (i_ctx_p == NULL) - return 0; - if (check_file_permissions_reduced(i_ctx_p, fname, flen, NULL, "PermitFileReading") < 0) - return_error(gs_error_invalidfileaccess); - return 0; -} - /* return zero for success, -ve for error, +1 for continue */ static int lib_file_open_search_with_no_combine(gs_file_path_ptr lib_path, const gs_memory_t *mem, i_ctx_t *i_ctx_p, @@ -1006,16 +995,17 @@ lib_file_open_search_with_no_combine(gs_file_path_ptr lib_path, const gs_memory stream *s; uint blen1 = blen; struct stat fstat; + int code = 1; if (gp_file_name_reduce(fname, flen, buffer, &blen1) != gp_combine_success) goto skip; - if (starting_arg_file || check_file_permissions_aux(i_ctx_p, buffer, blen1) >= 0) { + if (starting_arg_file || check_file_permissions(i_ctx_p, buffer, blen1, iodev, "PermitFileReading") >= 0) { if (iodev_os_open_file(iodev, (const char *)buffer, blen1, (const char *)fmode, &s, (gs_memory_t *)mem) == 0) { *pclen = blen1; make_stream_file(pfile, s, "r"); - return 0; + code = 0; } } else { @@ -1024,12 +1014,12 @@ lib_file_open_search_with_no_combine(gs_file_path_ptr lib_path, const gs_memory * Otherwise, keep searching. */ if ((*iodev->procs.file_status)(iodev, buffer, &fstat) >= 0) { - return_error(gs_error_invalidfileaccess); + code = gs_note_error(gs_error_invalidfileaccess); } } skip: - return 1; + return code; } /* return zero for success, -ve for error, +1 for continue */ @@ -1041,8 +1031,9 @@ lib_file_open_search_with_combine(gs_file_path_ptr lib_path, const gs_memory_t stream *s; const gs_file_path *pfpath = lib_path; uint pi; + int code = 1; - for (pi = 0; pi < r_size(&pfpath->list); ++pi) { + for (pi = 0; pi < r_size(&pfpath->list) && code == 1; ++pi) { const ref *prdir = pfpath->list.value.refs + pi; const char *pstr = (const char *)prdir->value.const_bytes; uint plen = r_size(prdir), blen1 = blen; @@ -1052,46 +1043,57 @@ lib_file_open_search_with_combine(gs_file_path_ptr lib_path, const gs_memory_t /* We need to concatenate and parse the file name here * if this path has a %device% prefix. */ if (pstr[0] == '%') { - int code; - /* We concatenate directly since gp_file_name_combine_* * rules are not correct for other devices such as %rom% */ code = gs_parse_file_name(&pname, pstr, plen, mem); - if (code < 0) + if (code < 0) { + code = 1; continue; + } if (blen < max(pname.len, plen) + flen) return_error(gs_error_limitcheck); memcpy(buffer, pname.fname, pname.len); memcpy(buffer+pname.len, fname, flen); code = pname.iodev->procs.open_file(pname.iodev, buffer, pname.len + flen, fmode, &s, (gs_memory_t *)mem); - if (code < 0) + if (code < 0) { + code = 1; continue; + } make_stream_file(pfile, s, "r"); /* fill in the buffer with the device concatenated */ memcpy(buffer, pstr, plen); memcpy(buffer+plen, fname, flen); *pclen = plen + flen; - return 0; + code = 0; } else { r = gp_file_name_combine(pstr, plen, fname, flen, false, buffer, &blen1); if (r != gp_combine_success) continue; - if (iodev_os_open_file(iodev, (const char *)buffer, blen1, (const char *)fmode, - &s, (gs_memory_t *)mem) == 0) { - if (starting_arg_file || - check_file_permissions_aux(i_ctx_p, buffer, blen1) >= 0) { + if (starting_arg_file || check_file_permissions(i_ctx_p, buffer, + blen1, iodev, "PermitFileReading") >= 0) { + + if (iodev_os_open_file(iodev, (const char *)buffer, blen1, + (const char *)fmode, &s, (gs_memory_t *)mem) == 0) { *pclen = blen1; make_stream_file(pfile, s, "r"); - return 0; + code = 0; + } + } + else { + struct stat fstat; + /* If we are not allowed to open the file by check_file_permissions_aux() + * and if the file exists, throw an error....... + * Otherwise, keep searching. + */ + if ((*iodev->procs.file_status)(iodev, (const char *)buffer, &fstat) >= 0) { + code = gs_note_error(gs_error_invalidfileaccess); } - sclose(s); - return_error(gs_error_invalidfileaccess); } } } - return 1; + return code; } /* Return a file object of of the file searched for using the search paths. */ |