Skip to content

Commit

Permalink
Merged PR 13255: [5.0 MSRC] Ensure that extracted bundle does not use…
Browse files Browse the repository at this point in the history
… preexisting files. (#53374)

Changed location of the extraction root directory on Unix:
-  from ` $TMPDIR\.net\ `     typical path is   ` \var\tmp\.net\userName\AppName\App.ID\stuff `
-  to  ` $HOME\.net\ `          typical path is   ` \home\userName\.net\AppName\App.ID\stuff `
  • Loading branch information
VSadov committed May 28, 2021
1 parent d43e886 commit 422b513
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 56 deletions.
2 changes: 1 addition & 1 deletion src/native/corehost/bundle/extractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pal::string_t& extractor_t::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 a read-write temp-directory couldn't be created."));
trace::error(_X("DOTNET_BUNDLE_EXTRACT_BASE_DIR is not set, and a read-write cache directory couldn't be created."));
throw StatusCode::BundleExtractionFailure;
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/native/corehost/hostmisc/pal.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,7 @@ namespace pal
bool get_default_breadcrumb_store(string_t* recv);
bool is_path_rooted(const string_t& path);

bool get_temp_directory(string_t& tmp_dir);

// Returns a platform-specific, user-private directory within get_temp_directory()
// Returns a platform-specific, user-private directory
// that can be used for extracting out components of a single-file app.
bool get_default_bundle_extraction_base_dir(string_t& extraction_dir);

Expand Down
56 changes: 8 additions & 48 deletions src/native/corehost/hostmisc/pal.unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,80 +343,40 @@ bool is_read_write_able_directory(pal::string_t& dir)
(access(dir.c_str(), R_OK | W_OK | X_OK) == 0);
}

bool pal::get_temp_directory(pal::string_t& tmp_dir)
bool get_extraction_base_parent_directory(pal::string_t& directory)
{
// First, check for the POSIX standard environment variable
if (getenv(_X("TMPDIR"), &tmp_dir))
// check for the POSIX standard environment variable
if (pal::getenv(_X("HOME"), &directory))
{
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 (is_read_write_able_directory(_var_tmp))
{
tmp_dir.assign(_var_tmp);
return true;
}

pal::string_t _tmp = _X("/tmp/");
if (is_read_write_able_directory(_tmp))
{
tmp_dir.assign(_tmp);
return true;
return is_read_write_able_directory(directory);
}

return false;
}

bool pal::get_default_bundle_extraction_base_dir(pal::string_t& extraction_dir)
{
if (!get_temp_directory(extraction_dir))
if (!get_extraction_base_parent_directory(extraction_dir))
{
return false;
}

append_path(&extraction_dir, _X(".net"));
pal::string_t dotnetdir(extraction_dir);

// getuid() is the real user ID, and the call has no defined errors.
struct passwd* passwd = getpwuid(getuid());
if (passwd == nullptr || passwd->pw_name == nullptr)
{
return false;
}

append_path(&extraction_dir, passwd->pw_name);

if (is_read_write_able_directory(extraction_dir))
{
return true;
}

// Create $TMPDIR/.net accessible to everyone
if (::mkdir(dotnetdir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == 0)
// Create $HOME/.net with rwx access to the owner
if (::mkdir(extraction_dir.c_str(), S_IRWXU) == 0)
{
// In the above mkdir() system call, some permissions are strangely dropped!
// Linux drops S_IWO and Mac drops S_IWG | S_IWO.
// So these are again explicitly set by calling chmod()
if (chmod(dotnetdir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) != 0)
{
return false;
}
return true;
}
else if (errno != EEXIST)
{
return false;
}

// Create $TMPDIR/.net/username accessible only to the user
if (::mkdir(extraction_dir.c_str(), S_IRWXU | S_ISVTX) != 0 && errno != EEXIST)
{
return false;
}

return is_read_write_able_directory(extraction_dir);
}

Expand Down
8 changes: 4 additions & 4 deletions src/native/corehost/hostmisc/pal.windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ bool pal::get_module_path(dll_t mod, string_t* recv)
return GetModuleFileNameWrapper(mod, recv);
}

bool pal::get_temp_directory(pal::string_t& tmp_dir)
bool get_extraction_base_parent_directory(pal::string_t& directory)
{
const size_t max_len = MAX_PATH + 1;
pal::char_t temp_path[max_len];
Expand All @@ -581,14 +581,14 @@ bool pal::get_temp_directory(pal::string_t& tmp_dir)
}

assert(len < max_len);
tmp_dir.assign(temp_path);
directory.assign(temp_path);

return realpath(&tmp_dir);
return pal::realpath(&directory);
}

bool pal::get_default_bundle_extraction_base_dir(pal::string_t& extraction_dir)
{
if (!get_temp_directory(extraction_dir))
if (!get_extraction_base_parent_directory(extraction_dir))
{
return false;
}
Expand Down

0 comments on commit 422b513

Please sign in to comment.