From 7db3ca4697416797f58ff478f3b28427c988493f Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 30 Aug 2020 00:12:49 +0100 Subject: [PATCH] avoid changing deliver_homw --- src/src/transports/appendfile.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c index 95857a53e..a3bc3fe3d 100644 --- a/src/src/transports/appendfile.c +++ b/src/src/transports/appendfile.c @@ -888,22 +888,23 @@ we can't do any tests. Arguments: filename the file name create_file the ob->create_file option + deliver_dir the delivery directory Returns: TRUE if creation is permitted */ static BOOL -check_creation(uschar *filename, int create_file) +check_creation(uschar *filename, int create_file, const uschar * deliver_dir) { BOOL yield = TRUE; -if (deliver_home && create_file != create_anywhere) +if (deliver_dir && create_file != create_anywhere) { - int len = Ustrlen(deliver_home); + int len = Ustrlen(deliver_dir); uschar *file = filename; while (file[0] == '/' && file[1] == '/') file++; - if ( Ustrncmp(file, deliver_home, len) != 0 + if ( Ustrncmp(file, deliver_dir, len) != 0 || file[len] != '/' || Ustrchr(file+len+2, '/') != NULL && ( create_file != create_belowhome @@ -946,10 +947,10 @@ if (deliver_home && create_file != create_anywhere) if (rp) { uschar hdbuffer[PATH_MAX+1]; - uschar *rph = deliver_home; + const uschar * rph = deliver_dir; int rlen = Ustrlen(big_buffer); - if ((rp = US realpath(CS deliver_home, CS hdbuffer))) + if ((rp = US realpath(CS deliver_dir, CS hdbuffer))) { rph = hdbuffer; len = Ustrlen(rph); @@ -960,7 +961,7 @@ if (deliver_home && create_file != create_anywhere) { yield = FALSE; DEBUG(D_transport) debug_printf("Real path \"%s\" does not match \"%s\"\n", - big_buffer, deliver_home); + big_buffer, deliver_dir); } } } @@ -1130,6 +1131,7 @@ appendfile_transport_entry( appendfile_transport_options_block *ob = (appendfile_transport_options_block *)(tblock->options_block); struct stat statbuf; +const uschar * deliver_dir; uschar *fdname = NULL; uschar *filename = NULL; uschar *hitchname = NULL; @@ -1312,8 +1314,8 @@ if (f.dont_deliver) /* If an absolute path was given for create_file the it overrides deliver_home (here) and de-taints the filename (below, after check_creation() */ -if (*ob->create_file_string == '/') - deliver_home = ob->create_file_string; +deliver_dir = *ob->create_file_string == '/' + ? ob->create_file_string : deliver_home; /* Handle the case of a file name. If the file name is /dev/null, we can save ourselves some effort and just give a success return right away. */ @@ -1334,9 +1336,8 @@ if (!isdirectory) is written, and find out if we are permitted to create a non-existent file. If the create_file option is an absolute path and the file was within it, de-taint. Chaeck for a tainted path. */ -/*XXX could we just de-taint on belowhome? */ - if ( (allow_creation_here = check_creation(path, ob->create_file)) + if ( (allow_creation_here = check_creation(path, ob->create_file, deliver_dir)) && ob->create_file == create_belowhome) if (is_tainted(path)) { @@ -2165,7 +2166,8 @@ else uschar *check_path; /* Default quota check path */ const pcre *regex = NULL; /* Regex for file size from file name */ - if (!check_creation(string_sprintf("%s/any", path), ob->create_file)) + if (!check_creation(string_sprintf("%s/any", path), + ob->create_file, deliver_dir)) { addr->basic_errno = ERRNO_BADCREATE; addr->message = string_sprintf("tried to create file in %s, but " -- 2.30.2