BundleExtraction: Determine extraction part based on writability. (dotnet/core-setup...
authorSwaroop Sridhar <Swaroop.Sridhar@microsoft.com>
Tue, 15 Oct 2019 20:25:23 +0000 (13:25 -0700)
committerGitHub <noreply@github.com>
Tue, 15 Oct 2019 20:25:23 +0000 (13:25 -0700)
On Unix systms where $TMPDIR is not set, temp-directory is currently
determined as:

/var/tmp/... (if it exists)
/tmp (if not)

However, this causes failures on systems where /var/tmp exists, but is not
writable (as is the case in AWS lambda).

This change fixes the issue with a writability check.

Fix dotnet/core-setup#7940

Commit migrated from https://github.com/dotnet/core-setup/commit/b2bff948e10f7632a40799808f4d7c74b912df80

src/installer/corehost/cli/apphost/bundle/extractor.cpp
src/installer/corehost/common/pal.unix.cpp

index 2f47e86..282e396 100644 (file)
@@ -23,6 +23,7 @@ void extractor_t::determine_extraction_dir()
         {
             trace::error(_X("Failure processing application bundle."));
             trace::error(_X("Failed to determine location for extracting embedded files."));
+            trace::error(_X("DOTNET_BUNDLE_EXTRACT_BASE_DIR is not set, and temp-directory doesn't exist or is not readable/writable."));
             throw StatusCode::BundleExtractionFailure;
         }
 
index 2fae9b5..bf22be3 100644 (file)
@@ -297,26 +297,32 @@ bool pal::get_default_servicing_directory(string_t* recv)
     return true;
 }
 
+bool is_read_write_able_directory(pal::string_t& dir)
+{
+    return pal::realpath(&dir) &&
+           (access(dir.c_str(), R_OK | W_OK | X_OK) == 0);
+}
+
 bool pal::get_temp_directory(pal::string_t& tmp_dir)
 {
     // First, check for the POSIX standard environment variable
     if (pal::getenv(_X("TMPDIR"), &tmp_dir))
     {
-        return pal::realpath(&tmp_dir);
+        return is_read_write_able_directory(tmp_dir);
     }
 
     // On non-compliant systems (ex: Ubuntu) try /var/tmp or /tmp directories.
     // /var/tmp is prefered since its contents are expected to survive across
     // machine reboot.
     pal::string_t _var_tmp = _X("/var/tmp/");
-    if (pal::realpath(&_var_tmp))
+    if (is_read_write_able_directory(_var_tmp))
     {
         tmp_dir.assign(_var_tmp);
         return true;
     }
 
     pal::string_t _tmp = _X("/tmp/");
-    if (pal::realpath(&_tmp))
+    if (is_read_write_able_directory(_tmp))
     {
         tmp_dir.assign(_tmp);
         return true;