Description: fix info disclosure via insecure temporary directory use
Origin: backport, http://icedtea.classpath.org/hg/release/icedtea-web-1.4/rev/35f4d27451fd
Origin: backport, http://icedtea.classpath.org/hg/release/icedtea-web-1.4/rev/1ae3613c82f2
Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2013-6493

Index: icedtea-web-1.4.1/plugin/icedteanp/IcedTeaNPPlugin.cc
===================================================================
--- icedtea-web-1.4.1.orig/plugin/icedteanp/IcedTeaNPPlugin.cc	2014-03-04 14:51:03.000000000 -0500
+++ icedtea-web-1.4.1/plugin/icedteanp/IcedTeaNPPlugin.cc	2014-03-04 14:55:00.683576417 -0500
@@ -38,6 +38,9 @@
 
 // System includes.
 #include <dlfcn.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
 #include <errno.h>
 #include <libgen.h>
 #include <stdio.h>
@@ -133,6 +136,7 @@
 
 // Data directory for plugin.
 static std::string data_directory;
+static DIR *data_directory_descriptor;
 
 // Fully-qualified appletviewer default  executable and rt.jar
 static const char* appletviewer_default_executable = ICEDTEA_WEB_JRE "/bin/java";
@@ -206,7 +210,7 @@
 NPError get_cookie_info(const char* siteAddr, char** cookieString, uint32_t* len);
 NPError get_proxy_info(const char* siteAddr, char** proxy, uint32_t* len);
 void consume_message(gchar* message);
-void start_jvm_if_needed();
+NPError start_jvm_if_needed();
 static void appletviewer_monitor(GPid pid, gint status, gpointer data);
 void plugin_send_initialization_message(char* instance, gulong handle,
                                                int width, int height,
@@ -281,7 +285,21 @@
       return appletviewer_default_rtjar;      
 }
 
-
+static void cleanUpDir(){
+  //free data_directory descriptor 
+  if (data_directory_descriptor != NULL) {
+    closedir(data_directory_descriptor);
+  }
+  //clean up pipes directory
+  PLUGIN_DEBUG ("Removing runtime directory %s \n", data_directory.c_str());
+  int removed = rmdir(data_directory.c_str());
+  if (removed != 0) {
+    PLUGIN_ERROR_THREE ("Failed to remove runtime directory %s, because of  %s \n", data_directory.c_str(), strerror(errno));
+  } else {
+    PLUGIN_DEBUG ("Removed runtime directory %s \n", data_directory.c_str());
+  }
+  data_directory_descriptor = NULL;
+}
 /* 
  * Find first member in GHashTable* depending on version of glib
  */
@@ -346,6 +364,7 @@
   gchar* cookie_info = NULL;
 
   NPObject* npPluginObj = NULL;
+  NPError startup_error = NPERR_NO_ERROR; 
 
   if (!instance)
     {
@@ -364,7 +383,7 @@
     }
 
   // start the jvm if needed
-  start_jvm_if_needed();
+  startup_error = start_jvm_if_needed();
 
   // Initialize data->instance_id.
   //
@@ -436,7 +455,7 @@
 }
 
 // Starts the JVM if it is not already running
-void start_jvm_if_needed()
+NPError start_jvm_if_needed()
 {
 
   // This is asynchronized function. It must
@@ -451,7 +470,7 @@
   if (jvm_up)
   {
       PLUGIN_DEBUG("JVM is up. Returning.\n");
-      return;
+      return  NPERR_NO_ERROR;
   }
 
   PLUGIN_DEBUG("No JVM is running. Attempting to start one...\n");
@@ -619,10 +638,12 @@
   g_free (in_pipe_name);
   in_pipe_name = NULL;
 
+  cleanUpDir();
  done:
 
   // Now other threads may re-enter.. unlock the mutex
   g_mutex_unlock(vm_start_mutex);
+  return np_error;
 
 }
 
@@ -1899,53 +1920,30 @@
   // Make sure the plugin data directory exists, creating it if
   // necessary.
 
-  const char* tmpdir_env = getenv("TMPDIR");
-  if (tmpdir_env != NULL && g_file_test (tmpdir_env,
-                    (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
-    {
-      data_directory = tmpdir_env;
-    }
-  else if (g_file_test (P_tmpdir,
-                    (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
-    {
-      data_directory = P_tmpdir;
-    }
-  else
-    {
-      // If TMPDIR and P_tmpdir do not exist, try /tmp directly
-      data_directory = "/tmp";
-    }
-
-  data_directory += "/icedteaplugin-";
-  if (getenv("USER") != NULL)
-      data_directory += getenv("USER");
-
+  data_directory = IcedTeaPluginUtilities::getRuntimePath() + "/icedteaplugin-";
+  if (getenv("USER") != NULL) {
+    data_directory = data_directory + getenv("USER") + "-";
+  }
+  data_directory += "XXXXXX";
   // Now create a icedteaplugin subdir
-  if (!g_file_test (data_directory.c_str(),
-                    (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
-    {
-      int file_error = 0;
-
-      file_error = g_mkdir (data_directory.c_str(), 0700);
-      if (file_error != 0)
-        {
-          PLUGIN_ERROR_THREE ("Failed to create data directory",
-                          data_directory.c_str(),
-                          strerror (errno));
-          return NPERR_GENERIC_ERROR;
-        }
-    }
-
+  char fileNameX[data_directory.length()+1];
+  std::strcpy (fileNameX, data_directory.c_str());
+  char * fileName = mkdtemp(fileNameX);
+  if (fileName == NULL) {
+    PLUGIN_ERROR_THREE ("Failed to create data directory %s, %s\n",
+                        data_directory.c_str(),
+                        strerror (errno));
+    return NPERR_GENERIC_ERROR;
+  }
+  data_directory = std::string(fileName);
 
-  // If data directory doesn't exist by this point, bail
-  if (!g_file_test (data_directory.c_str(),
-                    (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
-    {
-      PLUGIN_ERROR_THREE ("Temp directory does not exist: ",
-                          data_directory.c_str(),
-                          strerror (errno));
+  //open uniques icedteaplugin subdir for one single run  
+  data_directory_descriptor = opendir(data_directory.c_str());
+  if (data_directory_descriptor == NULL) {
+      PLUGIN_ERROR_THREE ("Failed to open data directory %s %s\n",
+                      data_directory.c_str(), strerror (errno));
       return NPERR_GENERIC_ERROR;
-    }
+  }
 
   // Set appletviewer_executable.
   PLUGIN_DEBUG("Executing java at %s\n", get_plugin_executable().c_str());
@@ -2128,6 +2126,8 @@
   delete plugin_to_java_bus;
   //delete internal_bus;
 
+  cleanUpDir();
+  
   PLUGIN_DEBUG ("NP_Shutdown return\n");
 
   return NPERR_NO_ERROR;
Index: icedtea-web-1.4.1/plugin/icedteanp/IcedTeaPluginUtils.cc
===================================================================
--- icedtea-web-1.4.1.orig/plugin/icedteanp/IcedTeaPluginUtils.cc	2014-03-04 14:51:03.000000000 -0500
+++ icedtea-web-1.4.1/plugin/icedteanp/IcedTeaPluginUtils.cc	2014-03-04 14:51:39.227571022 -0500
@@ -1074,6 +1074,36 @@
 }
 
 
+std::string IcedTeaPluginUtilities::getTmpPath(){
+  const char* tmpdir_env = getenv("TMPDIR");
+  if (tmpdir_env != NULL && g_file_test (tmpdir_env,
+                    (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
+  {
+    return std::string(tmpdir_env);
+  }
+  else if (g_file_test (P_tmpdir,
+                    (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
+  {
+    return std::string(P_tmpdir);
+  }
+  else
+  {
+    // If TMPDIR and P_tmpdir do not exist, try /tmp directly
+    return "/tmp";
+  }
+}
+
+std::string IcedTeaPluginUtilities::getRuntimePath(){
+ const char* rntdir_env = getenv("XDG_RUNTIME_DIR");
+  if (rntdir_env != NULL && g_file_test (rntdir_env,
+                    (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
+  {
+    return std::string(rntdir_env);
+  }
+  return IcedTeaPluginUtilities::getTmpPath();
+}
+
+
 /******************************************
  * Begin JavaMessageSender implementation *
  ******************************************
Index: icedtea-web-1.4.1/plugin/icedteanp/IcedTeaPluginUtils.h
===================================================================
--- icedtea-web-1.4.1.orig/plugin/icedteanp/IcedTeaPluginUtils.h	2014-03-04 14:51:03.000000000 -0500
+++ icedtea-web-1.4.1/plugin/icedteanp/IcedTeaPluginUtils.h	2014-03-04 14:51:39.231571022 -0500
@@ -277,7 +277,8 @@
         /*cutting whitespaces from end and start of string*/
         static void trim(std::string& str);
         static bool file_exists(std::string filename);
-
+        static std::string getTmpPath();
+        static std::string getRuntimePath();
 };
 
 /*
