fofi/FoFiBase.cc | 3 +- fofi/FoFiIdentifier.cc | 3 +- glib/poppler-attachment.cc | 5 ++-- glib/poppler-media.cc | 5 ++-- goo/gfile.cc | 51 +++++++++++++++++++++++++++++++++++++++++++-- goo/gfile.h | 3 ++ poppler/CairoFontEngine.cc | 2 - poppler/FileSpec.cc | 3 +- poppler/GfxState.cc | 5 ++-- poppler/GlobalParams.cc | 4 +-- poppler/GlobalParamsWin.cc | 2 - poppler/PDFDoc.cc | 6 ++--- poppler/PSOutputDev.cc | 4 +-- poppler/TextOutputDev.cc | 3 +- splash/SplashBitmap.cc | 7 +++--- 15 files changed, 82 insertions(+), 24 deletions(-)
New commits: commit d5625de8ce3fc31608248fe14b12c4c7d1a43593 Author: Christian Persch <[email protected]> Date: Thu Jan 3 21:11:49 2019 +0100 gfile: Open files with CLOEXEC flag set First try to atomically open the file using O_CLOEXEC for open() and the "e" mode for fopen(), and if that doesn't work or O_CLOEXEC isn't defined, fall back to opening the file first and applying the FD_CLOEXEC flag afterwards. diff --git a/goo/gfile.cc b/goo/gfile.cc index c2973416..c33b580a 100644 --- a/goo/gfile.cc +++ b/goo/gfile.cc @@ -66,6 +66,8 @@ #ifndef _WIN32 +using namespace std::string_literals; + namespace { template< typename... > @@ -270,8 +272,33 @@ GooString *appendToPath(GooString *path, const char *fileName) { #endif } +static bool makeFileDescriptorCloexec(int fd) { +#ifdef FD_CLOEXEC + int flags = fcntl(fd, F_GETFD); + if (flags >= 0 && !(flags & FD_CLOEXEC)) + flags = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); + + return flags >= 0; +#else + return true; +#endif +} + int openFileDescriptor(const char *path, int flags) { - return open(path, flags); +#ifdef O_CLOEXEC + return open(path, flags | O_CLOEXEC); +#else + int fd = open(path, flags); + if (fd == -1) + return fd; + + if (!makeFileDescriptorCloexec(fd)) { + close(fd); + return -1; + } + + return fd; +#endif } FILE *openFile(const char *path, const char *mode) { @@ -333,7 +360,23 @@ FILE *openFile(const char *path, const char *mode) { return fopen(nPath, mode); } #else - return fopen(path, mode); + // First try to atomically open the file with CLOEXEC + const std::string modeStr = mode + "e"s; + FILE *file = fopen(path, modeStr.c_str()); + if (file != nullptr) + return file; + + // Fall back to the provided mode and apply CLOEXEC afterwards + file = fopen(path, mode); + if (file == nullptr) + return nullptr; + + if (!makeFileDescriptorCloexec(fileno(file))) { + fclose(file); + return nullptr; + } + + return file; #endif } commit 4a3eef323d72b06780c318f58917f884eecc812e Author: Christian Persch <[email protected]> Date: Thu Jan 3 21:11:49 2019 +0100 gfile: Add wrapper for open(3p) and use it instead of directly calling open This is in preparation to making the wrapper enforce the O_CLOEXEC flag. diff --git a/goo/gfile.cc b/goo/gfile.cc index 819559c0..c2973416 100644 --- a/goo/gfile.cc +++ b/goo/gfile.cc @@ -270,6 +270,10 @@ GooString *appendToPath(GooString *path, const char *fileName) { #endif } +int openFileDescriptor(const char *path, int flags) { + return open(path, flags); +} + FILE *openFile(const char *path, const char *mode) { #ifdef _WIN32 OSVERSIONINFO version; @@ -485,7 +489,7 @@ GooFile* GooFile::open(const GooString *fileName) { #ifdef VMS int fd = ::open(fileName->c_str(), Q_RDONLY, "ctx=stm"); #else - int fd = ::open(fileName->c_str(), O_RDONLY); + int fd = openFileDescriptor(fileName->c_str(), O_RDONLY); #endif return fd < 0 ? nullptr : new GooFile(fd); diff --git a/goo/gfile.h b/goo/gfile.h index bd58e6c0..b0b942fd 100644 --- a/goo/gfile.h +++ b/goo/gfile.h @@ -88,6 +88,9 @@ typedef long long Goffset; // string, denoting the current directory). Returns <path>. extern GooString *appendToPath(GooString *path, const char *fileName); +// Open a file descriptor +extern int openFileDescriptor(const char *path, int flags); + // Open a file. On Windows, this converts the path from UTF-8 to // UCS-2 and calls _wfopen (if available). On other OSes, this simply // calls fopen. diff --git a/poppler/CairoFontEngine.cc b/poppler/CairoFontEngine.cc index 4876ba00..3c132550 100644 --- a/poppler/CairoFontEngine.cc +++ b/poppler/CairoFontEngine.cc @@ -280,7 +280,7 @@ _ft_new_face (FT_Library lib, if (font_data == nullptr) { /* if we fail to mmap the file, just pass it to FreeType instead */ - tmpl.fd = open (filename, O_RDONLY); + tmpl.fd = openFileDescriptor (filename, O_RDONLY); if (tmpl.fd == -1) return _ft_new_face_uncached (lib, filename, font_data, font_data_len, face_out, font_face_out); commit e1e4457a235f6107c09d32994fc628efa9e7bd0e Author: Christian Persch <[email protected]> Date: Thu Jan 3 21:11:49 2019 +0100 all: Use the openFile fopen wrapper from gfile.h Use the openFile wrapper instead of calling fopen directly in the libraries. diff --git a/fofi/FoFiBase.cc b/fofi/FoFiBase.cc index ad5d0067..1337c0d0 100644 --- a/fofi/FoFiBase.cc +++ b/fofi/FoFiBase.cc @@ -26,6 +26,7 @@ #include <stdio.h> #include <limits.h> +#include "goo/gfile.h" #include "goo/gmem.h" #include "poppler/Error.h" #include "FoFiBase.h" @@ -51,7 +52,7 @@ char *FoFiBase::readFile(const char *fileName, int *fileLen) { char *buf; int n; - if (!(f = fopen(fileName, "rb"))) { + if (!(f = openFile(fileName, "rb"))) { error(errIO, -1, "Cannot open '{0:s}'", fileName); return nullptr; } diff --git a/fofi/FoFiIdentifier.cc b/fofi/FoFiIdentifier.cc index e557e92a..e6e4ba1b 100644 --- a/fofi/FoFiIdentifier.cc +++ b/fofi/FoFiIdentifier.cc @@ -24,6 +24,7 @@ #include <stdio.h> #include <string.h> #include <limits.h> +#include "goo/gfile.h" #include "FoFiIdentifier.h" //------------------------------------------------------------------------ @@ -184,7 +185,7 @@ private: FileReader *FileReader::make(const char *fileName) { FILE *fA; - if (!(fA = fopen(fileName, "rb"))) { + if (!(fA = openFile(fileName, "rb"))) { return nullptr; } return new FileReader(fA); diff --git a/glib/poppler-attachment.cc b/glib/poppler-attachment.cc index dd7064bf..ff09edcf 100644 --- a/glib/poppler-attachment.cc +++ b/glib/poppler-attachment.cc @@ -18,7 +18,8 @@ #include "config.h" #include <errno.h> -#include <glib/gstdio.h> + +#include <goo/gfile.h> #include "poppler.h" #include "poppler-private.h" @@ -173,7 +174,7 @@ poppler_attachment_save (PopplerAttachment *attachment, g_return_val_if_fail (POPPLER_IS_ATTACHMENT (attachment), FALSE); - f = g_fopen (filename, "wb"); + f = openFile (filename, "wb"); if (f == nullptr) { diff --git a/glib/poppler-media.cc b/glib/poppler-media.cc index ab5f4c0e..23689ae4 100644 --- a/glib/poppler-media.cc +++ b/glib/poppler-media.cc @@ -20,7 +20,8 @@ #include "config.h" #include <errno.h> -#include <glib/gstdio.h> + +#include <goo/gfile.h> #include "poppler-media.h" #include "poppler-private.h" @@ -214,7 +215,7 @@ poppler_media_save (PopplerMedia *poppler_media, g_return_val_if_fail (POPPLER_IS_MEDIA (poppler_media), FALSE); g_return_val_if_fail (poppler_media->stream.isStream(), FALSE); - f = g_fopen (filename, "wb"); + f = openFile (filename, "wb"); if (f == nullptr) { diff --git a/poppler/FileSpec.cc b/poppler/FileSpec.cc index 7c12da63..63452e6e 100644 --- a/poppler/FileSpec.cc +++ b/poppler/FileSpec.cc @@ -28,6 +28,7 @@ #include <config.h> #include "FileSpec.h" +#include "goo/gfile.h" EmbFile::EmbFile(Object &&efStream) { @@ -83,7 +84,7 @@ bool EmbFile::save(const char *path) { FILE *f; bool ret; - if (!(f = fopen(path, "wb"))) { + if (!(f = openFile(path, "wb"))) { return false; } ret = save2(f); diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc index c5a10000..14c7d47d 100644 --- a/poppler/GfxState.cc +++ b/poppler/GfxState.cc @@ -46,6 +46,7 @@ #include <stddef.h> #include <math.h> #include <string.h> +#include "goo/gfile.h" #include "goo/gmem.h" #include "Error.h" #include "Object.h" @@ -461,7 +462,7 @@ cmsHPROFILE loadColorProfile(const char *fileName) if (fileName[0] == '/') { // full path // check if open the file - if ((fp = fopen(fileName,"r")) != nullptr) { + if ((fp = openFile(fileName,"r")) != nullptr) { fclose(fp); hp = cmsOpenProfileFromFile(fileName,"r"); } @@ -471,7 +472,7 @@ cmsHPROFILE loadColorProfile(const char *fileName) GooString *path = new GooString(GLOBAL_COLOR_PROFILE_DIR); path->append(fileName); // check if open the file - if ((fp = fopen(path->c_str(),"r")) != nullptr) { + if ((fp = openFile(path->c_str(),"r")) != nullptr) { fclose(fp); hp = cmsOpenProfileFromFile(path->c_str(),"r"); } diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc index 9a670ce3..9ca0a428 100644 --- a/poppler/GlobalParams.cc +++ b/poppler/GlobalParams.cc @@ -1064,7 +1064,7 @@ void GlobalParams::setupBaseFonts(char *dir) { fileName = nullptr; if (dir) { fileName = appendToPath(new GooString(dir), displayFontTab[i].t1FileName); - if ((f = fopen(fileName->c_str(), "rb"))) { + if ((f = openFile(fileName->c_str(), "rb"))) { fclose(f); } else { delete fileName; @@ -1074,7 +1074,7 @@ void GlobalParams::setupBaseFonts(char *dir) { for (j = 0; !fileName && displayFontDirs[j]; ++j) { fileName = appendToPath(new GooString(displayFontDirs[j]), displayFontTab[i].t1FileName); - if ((f = fopen(fileName->c_str(), "rb"))) { + if ((f = openFile(fileName->c_str(), "rb"))) { fclose(f); } else { delete fileName; diff --git a/poppler/GlobalParamsWin.cc b/poppler/GlobalParamsWin.cc index 83ece3c5..86a28f41 100644 --- a/poppler/GlobalParamsWin.cc +++ b/poppler/GlobalParamsWin.cc @@ -216,7 +216,7 @@ static void GetWindowsFontDir(char *winFontDir, int cbWinFontDirLen) static bool FileExists(const char *path) { - FILE * f = fopen(path, "rb"); + FILE * f = openFile(path, "rb"); if (f) { fclose(f); return true; diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 93fa4464..12f29191 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -897,7 +897,7 @@ int PDFDoc::savePageAs(GooString *name, int pageNo) Ref *refPage = getCatalog()->getPageRef(pageNo); Object page = getXRef()->fetch(refPage->num, refPage->gen); - if (!(f = fopen(name->c_str(), "wb"))) { + if (!(f = openFile(name->c_str(), "wb"))) { error(errIO, -1, "Couldn't open file '{0:t}'", name); return errOpenFile; } @@ -1030,7 +1030,7 @@ int PDFDoc::saveAs(GooString *name, PDFWriteMode mode) { OutStream *outStr; int res; - if (!(f = fopen(name->c_str(), "wb"))) { + if (!(f = openFile(name->c_str(), "wb"))) { error(errIO, -1, "Couldn't open file '{0:t}'", name); return errOpenFile; } @@ -1062,7 +1062,7 @@ int PDFDoc::saveWithoutChangesAs(GooString *name) { OutStream *outStr; int res; - if (!(f = fopen(name->c_str(), "wb"))) { + if (!(f = openFile(name->c_str(), "wb"))) { error(errIO, -1, "Couldn't open file '{0:t}'", name); return errOpenFile; } diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc index 1eb75aec..6294f7ec 100644 --- a/poppler/PSOutputDev.cc +++ b/poppler/PSOutputDev.cc @@ -1141,7 +1141,7 @@ PSOutputDev::PSOutputDev(const char *fileName, PDFDoc *doc, #endif } else { fileTypeA = psFile; - if (!(f = fopen(fileName, "w"))) { + if (!(f = openFile(fileName, "w"))) { error(errIO, -1, "Couldn't open PostScript file '{0:s}'", fileName); ok = false; return; @@ -2309,7 +2309,7 @@ void PSOutputDev::setupExternalType1Font(GooString *fileName, GooString *psName) embFontList->append("\n"); // copy the font file - if (!(fontFile = fopen(fileName->c_str(), "rb"))) { + if (!(fontFile = openFile(fileName->c_str(), "rb"))) { error(errIO, -1, "Couldn't open external font file"); return; } diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc index 7a8f180c..f1ec40db 100644 --- a/poppler/TextOutputDev.cc +++ b/poppler/TextOutputDev.cc @@ -59,6 +59,7 @@ #include <fcntl.h> // for O_BINARY #include <io.h> // for setmode #endif +#include "goo/gfile.h" #include "goo/gmem.h" #include "goo/GooString.h" #include "goo/GooList.h" @@ -5637,7 +5638,7 @@ TextOutputDev::TextOutputDev(const char *fileName, bool physLayoutA, // keep DOS from munging the end-of-line characters setmode(fileno(stdout), O_BINARY); #endif - } else if ((outputStream = fopen(fileName, append ? "ab" : "wb"))) { + } else if ((outputStream = openFile(fileName, append ? "ab" : "wb"))) { needClose = true; } else { error(errIO, -1, "Couldn't open text file '{0:s}'", fileName); diff --git a/splash/SplashBitmap.cc b/splash/SplashBitmap.cc index 856fa084..7ce8b6f9 100644 --- a/splash/SplashBitmap.cc +++ b/splash/SplashBitmap.cc @@ -36,6 +36,7 @@ #include <string.h> #include <stdlib.h> #include <limits.h> +#include "goo/gfile.h" #include "goo/gmem.h" #include "SplashErrorCodes.h" #include "SplashBitmap.h" @@ -165,7 +166,7 @@ SplashError SplashBitmap::writePNMFile(char *fileName) { FILE *f; SplashError e; - if (!(f = fopen(fileName, "wb"))) { + if (!(f = openFile(fileName, "wb"))) { return splashErrOpenFile; } @@ -262,7 +263,7 @@ SplashError SplashBitmap::writeAlphaPGMFile(char *fileName) { if (!alpha) { return splashErrModeMismatch; } - if (!(f = fopen(fileName, "wb"))) { + if (!(f = openFile(fileName, "wb"))) { return splashErrOpenFile; } fprintf(f, "P5\n%d %d\n255\n", width, height); @@ -338,7 +339,7 @@ SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, const char FILE *f; SplashError e; - if (!(f = fopen(fileName, "wb"))) { + if (!(f = openFile(fileName, "wb"))) { return splashErrOpenFile; } _______________________________________________ poppler mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/poppler
