Description: Create safe temporary directories
 CVE-2011-4114: PAR packed files are extracted to unsafe and predictable
 temporary directories.
 .
 - create parent of cache directory (i.e. /tmp/par-USER) with mode 0700
 - if it already exists, make sure that (and bail out if not)
   - it's not a symlink
   - it's mode 0700
   - it's owned by USER
Origin: upstream
Bug: https://rt.cpan.org/Public/Bug/Display.html?id=69560
Bug-Debian: http://bugs.debian.org/650706
Forwarded: not-needed
Author: Salvatore Bonaccorso <carnil@debian.org>
Last-Update: 2011-12-13

--- a/myldr/mktmpdir.c
+++ b/myldr/mktmpdir.c
@@ -153,7 +153,38 @@
     stmpdir = malloc( stmp_len );
     stmpdir2 = malloc( stmp_len );
     sprintf(stmpdir2, "%s%s%s%s", tmpdir, dir_sep, subdirbuf_prefix, username);
-    my_mkdir(stmpdir2, 0755);
+#ifdef WIN32
+    _mkdir(stmpdir2);         /* FIXME bail if error (other than EEXIST) */
+#else
+    {
+        struct stat st;
+
+        if (mkdir(stmpdir2, 0700) == -1 && errno != EEXIST) {
+            fprintf(stderr, "%s: creation of private subdirectory %s failed (errno=%i)\n", 
+                    argv[0], stmpdir2, errno);
+            return NULL;
+        }
+
+        /* now check that:
+         * - stmpdir2 is a directory (and not a symlink)
+         * - stmpdir2 is owned by the user
+         * - stmpdir2 has mode 0700
+         */
+        if (lstat(stmpdir2, &st) == -1) {
+            fprintf(stderr, "%s: stat of private subdirectory %s failed (errno=%i)\n",
+                    argv[0], stmpdir2, errno);
+            return NULL;
+        }
+
+        if (!S_ISDIR(st.st_mode)
+            || st.st_uid != getuid()
+            || (st.st_mode & 0777) != 0700 ) {
+            fprintf(stderr, "%s: private subdirectory %s is unsafe\n",
+                    argv[0], stmpdir2);
+            return NULL;
+        }
+    }
+#endif
 
     /* Doesn't really work - XXX */
     val = par_getenv( "PATH" );
@@ -239,7 +270,7 @@
            a prior invocation crashed leaving garbage in a temp directory that
            might interfere. */
 
-        while (my_mkdir(stmpdir, 0755) == -1 && errno == EEXIST) {
+        while (my_mkdir(stmpdir, 0700) == -1 && errno == EEXIST) {
             sprintf(
                 stmpdir,
                 "%s%stemp-%u-%u%s",
