diff options
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/libutil/util.c | 31 |
2 files changed, 27 insertions, 5 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f0dee1328..c5f874375 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1001,6 +1001,7 @@ CHECK_SYMBOL_EXISTS(SOCK_SEQPACKET "sys/types.h;sys/socket.h" HAVE_SOCK_SEQPACKE CHECK_SYMBOL_EXISTS(I_SETSIG "sys/types.h;sys/ioctl.h" HAVE_SETSIG) CHECK_SYMBOL_EXISTS(O_ASYNC "sys/types.h;sys/fcntl.h" HAVE_OASYNC) CHECK_SYMBOL_EXISTS(O_NOFOLLOW "sys/types.h;sys/fcntl.h" HAVE_ONOFOLLOW) +CHECK_SYMBOL_EXISTS(O_CLOEXEC "sys/types.h;sys/fcntl.h" HAVE_OCLOEXEC) LIST(APPEND CMAKE_REQUIRED_INCLUDES "${LIBSSL_INCLUDE}") CHECK_SYMBOL_EXISTS(SSL_set_tlsext_host_name "openssl/ssl.h" HAVE_SSL_TLSEXT_HOSTNAME) CHECK_SYMBOL_EXISTS(dirfd "sys/types.h;unistd.h;dirent.h" HAVE_DIRFD) diff --git a/src/libutil/util.c b/src/libutil/util.c index 593baf522..86f1f24f6 100644 --- a/src/libutil/util.c +++ b/src/libutil/util.c @@ -2422,7 +2422,7 @@ rspamd_file_xopen (const char *fname, int oflags, guint mode, gboolean allow_symlink) { struct stat sb; - int fd; + int fd, flags = oflags; if (lstat (fname, &sb) == -1) { @@ -2431,18 +2431,39 @@ rspamd_file_xopen (const char *fname, int oflags, guint mode, } } else if (!S_ISREG (sb.st_mode)) { - return -1; + if (S_ISLNK (sb.st_mode)) { + if (!allow_symlink) { + return -1; + } + } + else { + return -1; + } } +#ifdef HAVE_OCLOEXEC + flags |= O_CLOEXEC; +#endif + #ifdef HAVE_ONOFOLLOW if (!allow_symlink) { - fd = open (fname, oflags | O_NOFOLLOW, mode); + flags |= O_NOFOLLOW; + fd = open (fname, flags, mode); } else { - fd = open (fname, oflags, mode); + fd = open (fname, flags, mode); } #else - fd = open (fname, oflags, mode); + fd = open (fname, flags, mode); +#endif + +#ifndef HAVE_OCLOEXEC + if (fcntl (fd, F_SETFD, FD_CLOEXEC) == -1) { + msg_warn ("fcntl failed: %d, '%s'", errno, strerror (errno)); + close (fd); + + return -1; + } #endif return (fd); |