diff options
author | Chris Liddell <chris.liddell@artifex.com> | 2019-05-07 11:30:15 +0100 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2019-05-29 10:20:25 +0100 |
commit | 7ecbfda92b4c8dbf6f6c2bf8fc82020a29219eff (patch) | |
tree | 3c7d13cfd0a3dfbe5b2730039c123397e23a15f4 /base/gpmisc.c | |
parent | 9de16a6637b73e35f79d2d622de403b24e6502f2 (diff) | |
download | ghostpdl-7ecbfda92b4c8dbf6f6c2bf8fc82020a29219eff.tar.gz |
Add use of new file access permissions to PS interp
(this is a squash of several commits from filesec branch)
Use errno to indicate invalidfileaccess
Integrate fontconfig with file access controls
fontconfig API has a call to retrieve all the directories about which fontconfig
knows, so we can get those, and add them to the paths from which we're permitted
to read.
Add (most of) the Postscript "managed" paths....
...to the access controls.
GenericResourceDir, ICCProfilesDir (reading) and temporary file directories for
read/write/control.
Add paths/files from C to the file access controls
The -I paths, environment variables and build time paths.
The command line specified output file, permit writing.
Lastly, the command line specified input file is added to the readable list,
interpreted, and then removed from the list.
Add the FONTPATH path list to permit read access control list.
I opted to do this in Postscript because the list is (normally) a colon
separated list of paths, which we split into an array of paths (in Postscript) -
it seems sensible to do this only once, both for storage and permissions.
Add a non-standard string 'reverse search" operator
The search operator searches for the first occurrence of a character code in a
string (i.e. searches forwards from the start of the string), 'rsearch' finds
the last instance of a character code (i.e. search backwards from the end of
the string).
Fix gp_open_scratch_file_rm for access permissions
i.e. the same as gp_open_scratch_file
Handle clist file 'rewind' failures
'Rewinding' clist files may involved closing and recreating the temporary files,
which conceivably can fail, but the clist procs rewind method was a void
function, so couldn't return an error.
It now can, and does return an error, and we handle the error.
Add file permissions support for piped output.
Paths from Fontmap to PermitReading list
cidfmap paths, add to PermitReading list
Add command line options for path access control addition
--permit-file-read
--permit-file-write
--permit-file-control
--permit-file-all
They all take a separated list of paths (the usual platform specific ':' or ';'
separator), and to the respective access control lists - the final 'all' option
adds the paths to all the control lists.
Add file access control to the 'gp_stat' method.
This is complicated by the need to add the memory allocator context to the
gp_stat parameters. To facilitate this, I've added a gs_memory_t pointer to the
gx_io_device structure, which is set during the io device initialisation at
startup.
mkromfs: Add dummy gp_stat_impl for Windows - saves quite a bit of pointless
build upheaval
Add file access protection to file enumeration.
The low level implementation of Postscript's filenameforall (*_enumerate_files)
needs to also honour file access protection.
This is has been complicated by requiring a gs_memory_t to be available where
it wasn't previously (in order to access the gs_lib_ctx and the file permissions
lists therein).
Temp
Diffstat (limited to 'base/gpmisc.c')
-rw-r--r-- | base/gpmisc.c | 71 |
1 files changed, 59 insertions, 12 deletions
diff --git a/base/gpmisc.c b/base/gpmisc.c index 088265015..dc1231c96 100644 --- a/base/gpmisc.c +++ b/base/gpmisc.c @@ -16,6 +16,7 @@ /* Miscellaneous support for platform facilities */ +#include "errno_.h" #include "stat_.h" #include "unistd_.h" #include "fcntl_.h" @@ -801,8 +802,11 @@ gp_open_scratch_file_rm(const gs_memory_t *mem, { gp_file *file; - if (gp_validate_path(mem, fname, mode) != 0) - return NULL; + /* If the prefix is absolute, then we must check it's a permissible + * path. If not, we're OK. */ + if (gp_file_name_is_absolute(prefix, strlen(prefix)) && + gp_validate_path(mem, prefix, mode) != 0) + return NULL; file = gp_file_FILE_alloc(mem); if (file == NULL) @@ -819,17 +823,41 @@ gp_open_scratch_file_rm(const gs_memory_t *mem, return file; } -static int -ends_in(const char *first, const char *last, const char *ds, size_t len) +int +gp_stat(const gs_memory_t *mem, const char *path, struct stat *buf) { - while (len) { - if (last < first) - return 0; /* No match */ - if (*last != ds[--len]) - return 0; /* No match */ - last--; + if (gp_validate_path(mem, path, "r") != 0) { + return -1; } - return 1; + + return gp_stat_impl(mem, path, buf); +} + +file_enum * +gp_enumerate_files_init(gs_memory_t *mem, const char *pat, uint patlen) +{ + return gp_enumerate_files_init_impl(mem, pat, patlen); +} + +uint +gp_enumerate_files_next(gs_memory_t *mem, file_enum * pfen, char *ptr, uint maxlen) +{ + uint code = 0; + + while (code == 0) { + code = gp_enumerate_files_next_impl(mem, pfen, ptr, maxlen); + if (code == ~0) break; + if (code > 0) { + if (gp_validate_path(mem, ptr, "r") != 0) + code = 0; + } + } + return code; +} +void +gp_enumerate_files_close(gs_memory_t *mem, file_enum * pfen) +{ + gp_enumerate_files_close_impl(mem, pfen); } /* Path validation: (FIXME: Move this somewhere better) @@ -867,6 +895,19 @@ ends_in(const char *first, const char *last, const char *ds, size_t len) */ static int +ends_in(const char *first, const char *last, const char *ds, size_t len) +{ + while (len) { + if (last < first) + return 0; /* No match */ + if (*last != ds[--len]) + return 0; /* No match */ + last--; + } + return 1; +} + +static int validate(const gs_memory_t *mem, const char *path, gs_path_control_t type) @@ -948,7 +989,9 @@ gp_validate_path(const gs_memory_t *mem, uint rlen; int code = 0; - if (mem->gs_lib_ctx->core->path_control_active == 0) + /* mem->gs_lib_ctx can be NULL when we're called from mkromfs */ + if (mem->gs_lib_ctx == NULL || + mem->gs_lib_ctx->core->path_control_active == 0) return 0; len = strlen(path); @@ -985,5 +1028,9 @@ gp_validate_path(const gs_memory_t *mem, code = gs_note_error(gs_error_invalidfileaccess); } gs_free_object(mem->non_gc_memory, buffer, "gp_validate_path"); +#ifdef EACCES + if (code == gs_error_invalidfileaccess) + errno = EACCES; +#endif return code; } |