X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/24623111ecf127cb91a9b91942af29e5b5dc40ca..fa1c8faf169384bebaa8d172f491574c45ae2aa4:/src/src/rda.c diff --git a/src/src/rda.c b/src/src/rda.c index 1ab9e2f40..7d329c580 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 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* 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 @@ -179,8 +180,10 @@ struct stat statbuf; /* Reading a file is a form of expansion; we wish to deny attackers the capability to specify the file name. */ -if ((*error = is_tainted2(filename, 0, "Tainted name '%s' for file read not permitted\n", filename))) +if (is_tainted(filename)) { + *error = string_sprintf("Tainted name '%s' for file read not permitted\n", + filename); *yield = FF_ERROR; return NULL; } @@ -282,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) { @@ -337,11 +340,11 @@ Returns: a suitable return for rda_interpret() */ static int -rda_extract(const 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) { const uschar * data; @@ -440,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; } @@ -463,7 +466,7 @@ Returns: FALSE if data missing */ static BOOL -rda_read_string(int fd, uschar **sp) +rda_read_string(int fd, uschar ** sp) { int len; @@ -474,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; } @@ -539,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; @@ -806,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; @@ -863,9 +866,9 @@ if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED || for (;;) { int i, reply_options; - address_item *addr; - uschar *recipient; - uschar *expandn[EXPAND_MAXN + 2]; + address_item * addr; + uschar * recipient, * s; + uschar * expandn[EXPAND_MAXN + 2]; /* First string is the address; NULL => end of addresses */ @@ -882,10 +885,11 @@ if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED || if ( read(fd, &addr->mode, sizeof(addr->mode)) != sizeof(addr->mode) || read(fd, &addr->flags, sizeof(addr->flags)) != sizeof(addr->flags) - || !rda_read_string(fd, &addr->prop.errors_address) + || !rda_read_string(fd, &s) || read(fd, &i, sizeof(i)) != sizeof(i) ) goto DISASTER; + addr->prop.errors_address = s; addr->prop.ignore_error = (i != 0); /* Next comes a possible setting for $thisaddress and any numerical @@ -905,7 +909,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]; } @@ -915,7 +919,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; @@ -959,16 +963,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);