From 2632889eca3018763375f85b31212712044c395f Mon Sep 17 00:00:00 2001 From: Philip Hazel Date: Wed, 22 Feb 2006 14:46:44 +0000 Subject: [PATCH] Put file-creating fopen() calls in content-scanning code in a wrapper that handles the mode. --- doc/doc-txt/ChangeLog | 13 +++++++++++- src/src/daemon.c | 5 ++--- src/src/demime.c | 4 ++-- src/src/exim.c | 46 ++++++++++++++++++++++++++++++++++++++++--- src/src/functions.h | 3 ++- src/src/malware.c | 4 ++-- src/src/mime.c | 8 ++++---- src/src/spool_mbox.c | 4 ++-- 8 files changed, 69 insertions(+), 18 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index be0fc0dac..6385f60de 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.309 2006/02/21 16:24:19 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.310 2006/02/22 14:46:44 ph10 Exp $ Change log file for Exim from version 4.21 ------------------------------------------- @@ -210,6 +210,17 @@ PH/40 Changed the default ident timeout from 30s to 5s. PH/41 Added support for the use of login_cap features, on those BSD systems that have them, for controlling the resources used by pipe deliveries. +PH/42 The content-scanning code uses fopen() to create files in which to put + message data. Previously it was not paying any attention to the mode of + the files. Exim runs with umask(0) because the rest of the code creates + files with open(), and sets the required mode explicitly. Thus, these + files were ending up world-writeable. This was not a big issue, because, + being within the spool directory, they were not world-accessible. I have + created a function called modefopen, which takes an additional mode + argument. It sets umask(777), creates the file, chmods it to the required + mode, then resets the umask. All the relevant calls to fopen() in the + content scanning code have been changed to use this function. + Exim version 4.60 ----------------- diff --git a/src/src/daemon.c b/src/src/daemon.c index fade1a8d8..f1912c40f 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/daemon.c,v 1.14 2006/02/07 11:19:00 ph10 Exp $ */ +/* $Cambridge: exim/src/src/daemon.c,v 1.15 2006/02/22 14:46:44 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -1414,11 +1414,10 @@ if (running_in_test_harness || write_pid) if (pid_file_path[0] == 0) pid_file_path = string_sprintf("%s/exim-daemon.pid", spool_directory); - f = Ufopen(pid_file_path, "wb"); + f = modefopen(pid_file_path, "wb", 0644); if (f != NULL) { (void)fprintf(f, "%d\n", (int)getpid()); - (void)fchmod(fileno(f), 0644); (void)fclose(f); DEBUG(D_any) debug_printf("pid written to %s\n", pid_file_path); } diff --git a/src/src/demime.c b/src/src/demime.c index 0ab787741..2eac6cde6 100644 --- a/src/src/demime.c +++ b/src/src/demime.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/demime.c,v 1.8 2005/08/01 14:41:25 ph10 Exp $ */ +/* $Cambridge: exim/src/src/demime.c,v 1.9 2006/02/22 14:46:44 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -256,7 +256,7 @@ int mime_get_dump_file(uschar *extension, FILE **f, uschar *info) { } while(result != -1); - *f = fopen(CS file_name,"wb+"); + *f = modefopen(file_name,"wb+",SPOOL_MODE); if (*f == NULL) { /* cannot open new dump file, disk full ? -> soft error */ (void)string_format(info, 1024,"unable to open dump file"); diff --git a/src/src/exim.c b/src/src/exim.c index 8d21a7f9d..44e0a9a14 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/exim.c,v 1.34 2006/02/21 16:24:19 ph10 Exp $ */ +/* $Cambridge: exim/src/src/exim.c,v 1.35 2006/02/22 14:46:44 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -375,6 +375,39 @@ va_end(ap); +/************************************************* +* Call fopen() with umask 777 and adjust mode * +*************************************************/ + +/* Exim runs with umask(0) so that files created with open() have the mode that +is specified in the open() call. However, there are some files, typically in +the spool directory, that are created with fopen(). They end up world-writeable +if no precautions are taken. Although the spool directory is not accessible to +the world, this is an untidiness. So this is a wrapper function for fopen() +that sorts out the mode of the created file. + +Arguments: + filename the file name + options the fopen() options + mode the required mode + +Returns: the fopened FILE or NULL +*/ + +FILE * +modefopen(uschar *filename, char *options, mode_t mode) +{ +FILE *f; +umask(0777); +f = Ufopen(filename, options); +umask(0); +if (f != NULL) (void)fchmod(fileno(f), mode); +return f; +} + + + + /************************************************* * Ensure stdin, stdout, and stderr exist * *************************************************/ @@ -1440,8 +1473,15 @@ message_id_external[0] = 'E'; message_id = message_id_external + 1; message_id[0] = 0; -/* Set the umask to zero so that any files that Exim creates are created -with the modes that it specifies. */ +/* Set the umask to zero so that any files that Exim creates using open() are +created with the modes that it specifies. NOTE: Files created with fopen() have +a problem, which was not recognized till rather late (February 2006). With this +umask, such files will be world writeable. (They are all content scanning files +in the spool directory, which isn't world-accessible, so this is not a +disaster, but it's untidy.) I don't want to change this overall setting, +however, because it will interact badly with the open() calls. Instead, there's +now a function called modefopen() that fiddles with the umask while calling +fopen(). */ umask(0); diff --git a/src/src/functions.h b/src/src/functions.h index e71d6bb90..fdcfd55d2 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/functions.h,v 1.21 2006/02/07 11:19:00 ph10 Exp $ */ +/* $Cambridge: exim/src/src/functions.h,v 1.22 2006/02/22 14:46:44 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -166,6 +166,7 @@ extern void moan_smtp_batch(uschar *, char *, ...); extern void moan_tell_someone(uschar *, address_item *, uschar *, char *, ...); extern BOOL moan_to_sender(int, error_block *, header_line *, FILE *, BOOL); +extern FILE *modefopen(uschar *, char *, mode_t); extern uschar *parse_extract_address(uschar *, uschar **, int *, int *, int *, BOOL); diff --git a/src/src/malware.c b/src/src/malware.c index bdf3348d5..7e3c587c9 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/malware.c,v 1.13 2005/08/02 18:24:14 tom Exp $ */ +/* $Cambridge: exim/src/src/malware.c,v 1.14 2006/02/22 14:46:44 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -873,7 +873,7 @@ int malware(uschar **listptr) { }; (void)string_format(file_name,1024,"%s/scan/%s/%s_scanner_output", spool_directory, message_id, message_id); - scanner_record = fopen(CS file_name,"wb"); + scanner_record = modefopen(file_name,"wb",SPOOL_MODE); if (scanner_record == NULL) { log_write(0, LOG_MAIN|LOG_PANIC, diff --git a/src/src/mime.c b/src/src/mime.c index e0ac66cbe..c215b7bcf 100644 --- a/src/src/mime.c +++ b/src/src/mime.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/mime.c,v 1.13 2005/11/15 10:08:25 ph10 Exp $ */ +/* $Cambridge: exim/src/src/mime.c,v 1.14 2006/02/22 14:46:44 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -241,10 +241,10 @@ FILE *mime_get_decode_file(uschar *pname, uschar *fname) { if ((pname != NULL) && (fname != NULL)) { (void)string_format(filename, 2048, "%s/%s", pname, fname); - f = fopen(CS filename,"wb+"); + f = modefopen(filename,"wb+",SPOOL_MODE); } else if (pname == NULL) { - f = fopen(CS fname,"wb+"); + f = modefopen(fname,"wb+",SPOOL_MODE); } else if (fname == NULL) { int file_nr = 0; @@ -261,7 +261,7 @@ FILE *mime_get_decode_file(uschar *pname, uschar *fname) { result = stat(CS filename,&mystat); } while(result != -1); - f = fopen(CS filename,"wb+"); + f = modefopen(filename,"wb+",SPOOL_MODE); }; /* set expansion variable */ diff --git a/src/src/spool_mbox.c b/src/src/spool_mbox.c index e96dca48f..008ff26e6 100644 --- a/src/src/spool_mbox.c +++ b/src/src/spool_mbox.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/spool_mbox.c,v 1.10 2005/08/01 14:41:25 ph10 Exp $ */ +/* $Cambridge: exim/src/src/spool_mbox.c,v 1.11 2006/02/22 14:46:44 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -56,7 +56,7 @@ FILE *spool_mbox(unsigned long *mbox_file_size) { /* open [message_id].eml file for writing */ (void)string_format(mbox_path, 1024, "%s/scan/%s/%s.eml", spool_directory, message_id, message_id); - mbox_file = Ufopen(mbox_path,"wb"); + mbox_file = modefopen(mbox_path,"wb",SPOOL_MODE); if (mbox_file == NULL) { debug_printf("unable to open file for writing: %s\n", mbox_path); -- 2.25.1