Put file-creating fopen() calls in content-scanning code in a wrapper
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Wed, 22 Feb 2006 14:46:44 +0000 (14:46 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Wed, 22 Feb 2006 14:46:44 +0000 (14:46 +0000)
that handles the mode.

doc/doc-txt/ChangeLog
src/src/daemon.c
src/src/demime.c
src/src/exim.c
src/src/functions.h
src/src/malware.c
src/src/mime.c
src/src/spool_mbox.c

index be0fc0dac0e395a5a7fa5de842c2a644287d5861..6385f60def9564cfebbdfa7a94cb6abb2c3bea44 100644 (file)
@@ -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
 -----------------
index fade1a8d845f544f6508ff702efffb4bb61d1578..f1912c40f160dcf19eb35b61497b5609d453d32c 100644 (file)
@@ -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);
     }
index 0ab7877412864722b58537debd7605b60c9dac0b..2eac6cde6ce37b87b7b62d470d3694774dc38c62 100644 (file)
@@ -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");
index 8d21a7f9d8fd4242b3b42d7a977142e6f22c7b26..44e0a9a14691b7766c04f0933ad4cf934703ea24 100644 (file)
@@ -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);
 
index e71d6bb9098d24e49a633238023232a5b21a4f6c..fdcfd55d21580fa7ad38604fbbc57f4610ec56b2 100644 (file)
@@ -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);
index bdf3348d5b0d62b1d418dc2ffaa80630c12909ac..7e3c587c971d1d4a7a329b6d4712072c4fb13845 100644 (file)
@@ -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,
index e0ac66cbe9f666969aa00b44708501474eb0353b..c215b7bcf159d430f6f631a34a2b6fb2a4ab92a2 100644 (file)
@@ -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 */
index e96dca48f25ef004a3ff6ec04a67a4c95257a7ff..008ff26e68d1c704ff76ab7628526932f0b5db22 100644 (file)
@@ -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);