[m-rev.] diff: use mkstemp for io.make_temp

Peter Wang novalazy at gmail.com
Mon Dec 6 14:57:01 AEDT 2010


Branches: main

Use mkstemp() to implement `io.make_temp' where possible.  The current
implementation generates highly predictable file names which is a problem for
security.  More importantly for us, the generated names are based on the
initial process ID only, so if the process forks a lot of child processes which
each want to make temporary files, this will lead to conflicts (e.g. mmc --make
with high enough number of jobs).

configure.in:
library/io.m:
        Check for mkstemp(), #defining MR_HAVE_MKSTEMP if it exists.

runtime/mercury_conf.h.in:
        Use mkstemp() to implement `io.make_temp' where possible.

diff --git a/configure.in b/configure.in
index de12f71..b6a4107 100644
--- a/configure.in
+++ b/configure.in
@@ -1199,7 +1199,7 @@ mercury_check_for_functions \
         grantpt unlockpt ptsname tcgetattr tcsetattr ioctl \
         access sleep opendir readdir closedir mkdir symlink readlink \
         gettimeofday setenv putenv _putenv posix_spawn sched_setaffinity \
-        sched_getcpu sched_yield
+        sched_getcpu sched_yield mkstemp
 
 #-----------------------------------------------------------------------------#
 
diff --git a/library/io.m b/library/io.m
index f0e506a..5bd8305 100644
--- a/library/io.m
+++ b/library/io.m
@@ -9971,8 +9971,6 @@ io.make_temp(Dir, Prefix, Name, !IO) :-
 % We should be using conditional compilation here to avoid these POSIX
 % dependencies.
 
-%#include <stdio.h>
-
 :- pragma foreign_decl("C", "
 #ifdef MR_HAVE_UNISTD_H
     #include <unistd.h>
@@ -9996,6 +9994,27 @@ io.make_temp(Dir, Prefix, Name, !IO) :-
     [will_not_call_mercury, promise_pure, tabled_for_io,
         does_not_affect_liveness],
 "{
+#ifdef MR_HAVE_MKSTEMP
+    int err, fd;
+
+    FileName = MR_make_string(MR_PROC_LABEL, ""%s%s%.5sXXXXXX"",
+        Dir, Sep, Prefix);
+    fd = mkstemp(FileName);
+    if (fd == -1) {
+        ML_maybe_make_err_msg(MR_TRUE, errno,
+            ""error opening temporary file: "", MR_PROC_LABEL, MR_TRUE,
+            ErrorMessage);
+        Error = -1;
+    } else {
+        do {
+            err = close(fd);
+        } while (err == -1 && MR_is_eintr(errno));
+        ML_maybe_make_err_msg(err, errno,
+            ""error closing temporary file: "", MR_PROC_LABEL, MR_TRUE,
+            ErrorMessage);
+        Error = err;
+    }
+#else
     /*
     ** Constructs a temporary name by concatenating Dir, `/', the first 5 chars
     ** of Prefix, three hex digits, '.', and 3 more hex digits. The six digit
@@ -10046,6 +10065,7 @@ io.make_temp(Dir, Prefix, Name, !IO) :-
             ErrorMessage);
         Error = err;
     }
+#endif
     MR_update_io(IO0, IO);
 }").
 
diff --git a/runtime/mercury_conf.h.in b/runtime/mercury_conf.h.in
index 7d81522..723697f 100644
--- a/runtime/mercury_conf.h.in
+++ b/runtime/mercury_conf.h.in
@@ -275,6 +275,7 @@
 **	MR_HAVE_SCHED_YIELD	we have the sched_yield() function.
 **	MR_HAVE_PTHREAD_MUTEXATTR_SETPSHARED we have the
 **				pthread_mutexattr_setpshared() function.
+**	MR_HAVE_MKSTEMP		we have the mkstemp() function.
 */
 #undef	MR_HAVE_GETPID
 #undef	MR_HAVE_SETPGID
@@ -310,6 +311,7 @@
 #undef	MR_HAVE_DUP
 #undef	MR_HAVE_DUP2
 #undef	MR_HAVE_FILENO
+#undef	MR_HAVE_MKSTEMP
 #undef	MR_HAVE_ISATTY
 #undef	MR_HAVE_GRANTPT
 #undef	MR_HAVE_UNLOCKPT
@@ -340,6 +342,7 @@
 #undef	MR_HAVE_SCHED_GETCPU
 #undef	MR_HAVE_SCHED_YIELD
 #undef	MR_HAVE_PTHREAD_MUTEXATTR_SETPSHARED
+#undef	MR_HAVE_MKSTEMP
 
 /*
 ** We use mprotect() and signals to catch stack and heap overflows.

--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list