git://git.exim.org
/
users
/
jgh
/
exim.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (from parent 1:
539410b
)
avoid changing deliver_homw
appendfile_safe_path
author
Jeremy Harris
<jgh146exb@wizmail.org>
Sat, 29 Aug 2020 23:12:49 +0000
(
00:12
+0100)
committer
Jeremy Harris
<jgh146exb@wizmail.org>
Sat, 29 Aug 2020 23:12:49 +0000
(
00:12
+0100)
src/src/transports/appendfile.c
patch
|
blob
|
history
diff --git
a/src/src/transports/appendfile.c
b/src/src/transports/appendfile.c
index 95857a53e01fb705687e60f7b5c2982eb1fbfa7f..a3bc3fe3d3b33fc27120288bc75aa77db574a7b5 100644
(file)
--- 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
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
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;
{
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++;
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
|| 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];
if (rp)
{
uschar hdbuffer[PATH_MAX+1];
-
uschar *rph = deliver_home
;
+
const uschar * rph = deliver_dir
;
int rlen = Ustrlen(big_buffer);
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);
{
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",
{
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;
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;
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 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. */
/* 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. */
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))
{
&& 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 */
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 "
{
addr->basic_errno = ERRNO_BADCREATE;
addr->message = string_sprintf("tried to create file in %s, but "