X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/46d2a5e6f6e7709d172903b13945d23fc0a2c888..a85c067ba6c6940512cf57ec213277a370d87e70:/src/src/rda.c diff --git a/src/src/rda.c b/src/src/rda.c index 0dc859107..1bc322e34 100644 --- a/src/src/rda.c +++ b/src/src/rda.c @@ -2,9 +2,10 @@ * Exim - an Internet mail transport agent * *************************************************/ +/* Copyright (c) The Exim maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ -/* Copyright (c) The Exim maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This module contains code for extracting addresses from a forwarding list (from an alias or forward file) or by running the filter interpreter. It may do @@ -42,7 +43,7 @@ Returns: FILTER_EXIM if it starts with "# Exim filter" static BOOL match_tag(const uschar *s, const uschar *tag) { -for (; *tag != 0; s++, tag++) +for (; *tag; s++, tag++) if (*tag == ' ') { while (*s == ' ' || *s == '\t') s++; @@ -60,10 +61,10 @@ tags for other types of filter. */ int rda_is_filter(const uschar *s) { -while (isspace(*s)) s++; /* Skips initial blank lines */ -if (match_tag(s, CUS"# exim filter")) return FILTER_EXIM; - else if (match_tag(s, CUS"# sieve filter")) return FILTER_SIEVE; - else return FILTER_FORWARD; +Uskip_whitespace(&s); /* Skips initial blank lines */ +if (match_tag(s, CUS"# exim filter")) return FILTER_EXIM; +else if (match_tag(s, CUS"# sieve filter")) return FILTER_SIEVE; +else return FILTER_FORWARD; } @@ -166,7 +167,7 @@ Returns: pointer to string in store; NULL on error */ static uschar * -rda_get_file_contents(redirect_block *rdata, int options, uschar **error, +rda_get_file_contents(const redirect_block *rdata, int options, uschar **error, int *yield) { FILE *fwd; @@ -222,7 +223,7 @@ if (!(fwd = Ufopen(filename, "rb"))) switch(errno) DEFAULT_ERROR: default: - *error = string_open_failed(errno, "%s", filename); + *error = string_open_failed("%s", filename); *yield = FF_ERROR; return NULL; } @@ -284,7 +285,7 @@ if (statbuf.st_size > MAX_FILTER_SIZE) /* Read the file in one go in order to minimize the time we have it open. */ -filebuf = store_get(statbuf.st_size + 1, is_tainted(filename)); +filebuf = store_get(statbuf.st_size + 1, filename); if (fread(filebuf, 1, statbuf.st_size, fwd) != statbuf.st_size) { @@ -339,13 +340,13 @@ Returns: a suitable return for rda_interpret() */ static int -rda_extract(redirect_block *rdata, int options, uschar *include_directory, - uschar *sieve_vacation_directory, uschar *sieve_enotify_mailto_owner, - uschar *sieve_useraddress, uschar *sieve_subaddress, - address_item **generated, uschar **error, error_block **eblockp, - int *filtertype) +rda_extract(const redirect_block * rdata, int options, + const uschar * include_directory, const uschar * sieve_vacation_directory, + const uschar * sieve_enotify_mailto_owner, const uschar * sieve_useraddress, + const uschar * sieve_subaddress, address_item ** generated, uschar ** error, + error_block ** eblockp, int * filtertype) { -uschar *data; +const uschar * data; if (rdata->isfile) { @@ -442,9 +443,9 @@ Returns: -1 on error, else 0 static int rda_write_string(int fd, const uschar *s) { -int len = (s == NULL)? 0 : Ustrlen(s) + 1; +int len = s ? Ustrlen(s) + 1 : 0; return ( write(fd, &len, sizeof(int)) != sizeof(int) - || (s != NULL && write(fd, s, len) != len) + || (s && write(fd, s, len) != len) ) ? -1 : 0; } @@ -476,7 +477,7 @@ else /* We know we have enough memory so disable the error on "len" */ /* coverity[tainted_data] */ /* We trust the data source, so untainted */ - if (read(fd, *sp = store_get(len, FALSE), len) != len) return FALSE; + if (read(fd, *sp = store_get(len, GET_UNTAINTED), len) != len) return FALSE; return TRUE; } @@ -541,11 +542,11 @@ Returns: values from extraction function, or FF_NONEXIST: */ int -rda_interpret(redirect_block *rdata, int options, uschar *include_directory, - uschar *sieve_vacation_directory, uschar *sieve_enotify_mailto_owner, - uschar *sieve_useraddress, uschar *sieve_subaddress, ugid_block *ugid, - address_item **generated, uschar **error, error_block **eblockp, - int *filtertype, uschar *rname) +rda_interpret(redirect_block * rdata, int options, + const uschar * include_directory, const uschar * sieve_vacation_directory, + const uschar * sieve_enotify_mailto_owner, const uschar * sieve_useraddress, + const uschar * sieve_subaddress, const ugid_block * ugid, address_item ** generated, + uschar ** error, error_block ** eblockp, int * filtertype, const uschar * rname) { int fd, rc, pfd[2]; int yield, status; @@ -618,9 +619,14 @@ search_tidyup(); if ((pid = exim_fork(US"router-interpret")) == 0) { header_line *waslast = header_last; /* Save last header */ + int fd_flags = -1; fd = pfd[pipe_write]; (void)close(pfd[pipe_read]); + + if ((fd_flags = fcntl(fd, F_GETFD)) == -1) goto bad; + if (fcntl(fd, F_SETFD, fd_flags | FD_CLOEXEC) == -1) goto bad; + exim_setugid(ugid->uid, ugid->gid, FALSE, rname); /* Addresses can get rewritten in filters; if we are not root or the exim @@ -803,7 +809,7 @@ if (eblockp) uschar *s; if (!rda_read_string(fd, &s)) goto DISASTER; if (!s) break; - e = store_get(sizeof(error_block), FALSE); + e = store_get(sizeof(error_block), GET_UNTAINTED); e->next = NULL; e->text1 = s; if (!rda_read_string(fd, &s)) goto DISASTER; @@ -902,7 +908,7 @@ if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED || if (i > 0) { - addr->pipe_expandn = store_get((i+1) * sizeof(uschar *), FALSE); + addr->pipe_expandn = store_get((i+1) * sizeof(uschar *), GET_UNTAINTED); addr->pipe_expandn[i] = NULL; while (--i >= 0) addr->pipe_expandn[i] = expandn[i]; } @@ -912,7 +918,7 @@ if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED || if (read(fd, &reply_options, sizeof(int)) != sizeof(int)) goto DISASTER; if ((reply_options & REPLY_EXISTS) != 0) { - addr->reply = store_get(sizeof(reply_item), FALSE); + addr->reply = store_get(sizeof(reply_item), GET_UNTAINTED); addr->reply->file_expand = (reply_options & REPLY_EXPAND) != 0; addr->reply->return_message = (reply_options & REPLY_RETURN) != 0; @@ -956,16 +962,14 @@ if (had_disaster) *error = string_sprintf("internal problem in %s: failure to transfer " "data from subprocess: status=%04x%s%s%s", rname, status, readerror, - (*error == NULL)? US"" : US": error=", - (*error == NULL)? US"" : *error); + *error ? US": error=" : US"", + *error ? *error : US""); log_write(0, LOG_MAIN|LOG_PANIC, "%s", *error); } else if (status != 0) - { log_write(0, LOG_MAIN|LOG_PANIC, "internal problem in %s: unexpected status " "%04x from redirect subprocess (but data correctly received)", rname, status); - } FINAL_EXIT: (void)close(fd);