{
int fd, off = 0, len;
-if ((fd = open(CS filename, O_RDONLY)) < 0)
+if ((fd = exim_open2(CS filename, O_RDONLY)) < 0)
{
log_write(0, LOG_MAIN | LOG_PANIC, "unable to open file for reading: %s",
filename);
}
/******************************************************************************/
+/* Time calculations */
+
static inline void
timesince(struct timeval * diff, const struct timeval * then)
{
#endif
}
+/******************************************************************************/
+/* Taint-checked file opens */
+
+static inline int
+exim_open2(const char *pathname, int flags)
+{
+if (!is_tainted(pathname)) return open(pathname, flags);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
+errno = EACCES;
+return -1;
+}
+static inline int
+exim_open(const char *pathname, int flags, mode_t mode)
+{
+if (!is_tainted(pathname)) return open(pathname, flags, mode);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
+errno = EACCES;
+return -1;
+}
+static inline int
+exim_openat(int dirfd, const char *pathname, int flags)
+{
+if (!is_tainted(pathname)) return openat(dirfd, pathname, flags);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
+errno = EACCES;
+return -1;
+}
+static inline int
+exim_openat4(int dirfd, const char *pathname, int flags, mode_t mode)
+{
+if (!is_tainted(pathname)) return openat(dirfd, pathname, flags, mode);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
+errno = EACCES;
+return -1;
+}
+
+static inline FILE *
+exim_fopen(const char *pathname, const char *mode)
+{
+if (!is_tainted(pathname)) return fopen(pathname, mode);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
+errno = EACCES;
+return NULL;
+}
+
#endif /* !MACRO_PREDEF */
#endif /* _FUNCTIONS_H_ */
if (*scanner_options != '/')
{
/* calc file size */
- if ((drweb_fd = open(CCS eml_filename, O_RDONLY)) == -1)
+ if ((drweb_fd = exim_open(CCS eml_filename, O_RDONLY)) == -1)
return m_panic_defer_3(scanent, NULL,
string_sprintf("can't open spool file %s: %s",
eml_filename, strerror(errno)),
malware_name = US"unknown";
/* re-open the scanner output file, look for name match */
- scanner_record = fopen(CS file_name, "rb");
- while (fgets(CS linebuffer, sizeof(linebuffer), scanner_record))
- {
- /* try match */
- if ((s = m_pcre_exec(cmdline_regex_re, linebuffer)))
+ scanner_record = Ufopen(file_name, "rb");
+ while (Ufgets(linebuffer, sizeof(linebuffer), scanner_record))
+ if ((s = m_pcre_exec(cmdline_regex_re, linebuffer))) /* try match */
malware_name = s;
- }
(void)fclose(scanner_record);
}
else /* no virus found */
malware_daemon_ctx.sock);
/* calc file size */
- if ((clam_fd = open(CS eml_filename, O_RDONLY)) < 0)
+ if ((clam_fd = exim_open2(CS eml_filename, O_RDONLY)) < 0)
{
int err = errno;
return m_panic_defer_3(scanent, NULL,
#define Uchdir(s) chdir(CCS(s))
#define Uchmod(s,n) chmod(CCS(s),n)
#define Ufgets(b,n,f) fgets(CS(b),n,f)
-#define Ufopen(s,t) fopen(CCS(s),CCS(t))
+#define Ufopen(s,t) exim_fopen(CCS(s),CCS(t))
#define Ulink(s,t) link(CCS(s),CCS(t))
#define Ulstat(s,t) lstat(CCS(s),t)
-#ifdef O_BINARY /* This is for Cygwin, */
-#define Uopen(s,n,m) open(CCS(s),(n)|O_BINARY,m) /* where all files must */
-#else /* be opened as binary */
-#define Uopen(s,n,m) open(CCS(s),n,m) /* to avoid problems */
-#endif /* with CRLF endings. */
+#ifdef O_BINARY /* This is for Cygwin, */
+#define Uopen(s,n,m) exim_open(CCS(s),(n)|O_BINARY,m) /* where all files must */
+#define Uopen2(s,n) exim_open2(CCS(s),(n)|O_BINARY)
+#else /* be opened as binary */
+#define Uopen(s,n,m) exim_open(CCS(s),n,m) /* to avoid problems */
+#define Uopen2(s,n) exim_open2(CCS(s),n)
+#endif /* with CRLF endings. */
#define Uread(f,b,l) read(f,CS(b),l)
#define Urename(s,t) rename(CCS(s),CCS(t))
#define Ustat(s,t) stat(CCS(s),t)
with a flag that fails symlinks. */
{
- int fd = open(CS directory, O_RDONLY);
+ int fd = exim_open2(CS directory, O_RDONLY);
if (fd < 0)
{
*error = string_sprintf("failed to open directory %s", directory);
temp = *p;
*p = '\0';
- fd2 = openat(fd, CS q, O_RDONLY|O_NOFOLLOW);
+ fd2 = exim_openat(fd, CS q, O_RDONLY|O_NOFOLLOW);
close(fd);
*p = temp;
if (fd2 < 0)
tb->name, srcpath, dstpath);
if ( (s = dstpath,
- (dstfd = openat(ddfd, CCS filename, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE))
+ (dstfd = exim_openat4(ddfd, CCS filename, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE))
< 0
)
|| is_hdr_file
- && (s = srcpath, (srcfd = openat(sdfd, CCS filename, O_RDONLY)) < 0)
+ && (s = srcpath, (srcfd = exim_openat(sdfd, CCS filename, O_RDONLY)) < 0)
)
op = US"opening";