Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bundle Extraction Directory: Default to a users-specific tmp directory on Unix systems #3846

Closed
swaroop-sridhar opened this issue Nov 21, 2019 · 10 comments
Assignees
Milestone

Comments

@swaroop-sridhar
Copy link
Contributor

In .net core 3, single file apps run by extracting the bundled contents to a temp directory.
The extraction directory is machine specific, and can be set through DOTNET_BUNDLE_EXTRACT_BASE_DIR environment variable.

When this setting is not configured, the host tries to use certain default directories.
On windows, extraction is within %TMPDIR%, which is user specific.
On Unix systems (like MAC) where $TMPDIR is set, extraction happens there -- and this is also user specific.
Otherwise, the extraction directory is within /var/tmp/ or /tmp/ which is common to all users, and may be locked by a specific user on first creation. Therefore, fix this issue by choosing something like /var/tmp/<user-id>/.net/... or $HOME/.net/....

This fix ameliorates the current problem, but is still robust -- especially within the TMP directory because any user can create a similar directory structure inaccessible to others. So the best way to configure the extraction directory is by setting BUNDLE_EXTRACTION_BASE_DIR.

@swaroop-sridhar swaroop-sridhar self-assigned this Nov 21, 2019
@am11
Copy link
Member

am11 commented Nov 22, 2019

Isn't the plan to forgo the entire bundle extraction mechanism in future, and read all bundle constituents from mmap?

@swaroop-sridhar
Copy link
Contributor Author

@am11 in .net 5, we'll reduce the reliance on extraction for single-file apps. However, extraction may still be supported for including custom native DLLs within the single-file app.

We also want to fix the extraction directory permission issue for a servicing fix to 3.1.

@swaroop-sridhar swaroop-sridhar changed the title Bundle Extraction Directory: On Linux systems where $TMPDIR is not set, default to a users-specific tmp directory. Bundle Extraction Directory: Default to a users-specific tmp directory on Unix systems Jan 26, 2020
@swaroop-sridhar
Copy link
Contributor Author

In order to fix this problem, a few options are:

  1. Set permissions of /var/tmp/.net/... as 777
    • Pros: Share extraction across all users
    • Cons: Shares the extraction across users
  2. Choose /var/tmp//.net as the default extraction location
    • Pros: Extraction cleaned up routinely
    • Cons: Anybody can create the /var/tmp// directory and lock out other users from executing single-file apps
  3. Choose $HOME/.net as the default extraction location
    • Pros: The directory is completely under user control
    • Cons: Not cleaned up by the system.
  4. Use a scheme similar to mkdtemp logic, as explained by @lpereira in this PR: single-file: Use unpredictable directory names on Unix designs#88
    • Pros: More robust tmp-directory creation logic, better guard against name-collisions
    • Cons: Maintains non-temp state, more complex logic.

If single-file bundles use extraction in .net 5 (for certain file types), we should use solution (4) above.

In .net 3.1 servicing fix, we’ll go after a simpler solution, by extracting to a user-specific directory:
/var/tmp/.net/<user-ID>/<app>/… , where /var/tmp/.net has permission 0777, and /var/tmp/.net/<user-ID>/… 0700.

@msftgits msftgits transferred this issue from dotnet/core-setup Jan 30, 2020
@msftgits msftgits added this to the 5.0 milestone Jan 30, 2020
swaroop-sridhar added a commit that referenced this issue Feb 12, 2020
…e-file apps (#2329)

In .net core 3, single file apps run by extracting the bundled contents to a temp directory.
The extraction directory is machine specific, and can be set through DOTNET_BUNDLE_EXTRACT_BASE_DIR environment variable.

When this setting is not configured, the host tries to use certain default directories.
On windows, extraction is within %TMPDIR%, which is user specific.
On Unix systems $TMPDIR/.net if set, which may be user specific (ex: MAC)
Otherwise, the extraction directory is within /var/tmp/ or /tmp/ which is common to all users, and may be locked by a specific user on first creation.

Therefore, this change fixes this issue by defaulting the extraction base directory in Unix systems to
`<temp-dir>/.net/<user-ID>` , where
`<temp-dir>/.net/` has permission 0777, and
`<temp-dir>/.net/<user-ID>/` has permission 01700.

This fix will be migrated to coreclr/3.1 branch for servicing.

Testing: Manual testing on Unix/Mac systems, since we don't have the setup to add automated tests with multiple users.

Issue #3846
@maryamariyan maryamariyan added the untriaged New issue has not been triaged by the area owner label Feb 23, 2020
@jeffschwMSFT jeffschwMSFT removed the untriaged New issue has not been triaged by the area owner label Feb 24, 2020
swaroop-sridhar added a commit to swaroop-sridhar/core-setup that referenced this issue Feb 28, 2020
…tory

dotnet/runtime#3846

On some Unix systems, multiple users cannot use single-file apps on the same machine.

In .net core 3, single file apps run by extracting the bundled contents to a temp directory.
The extraction directory is machine specific, and can be set through DOTNET_BUNDLE_EXTRACT_BASE_DIR environment variable.

When this setting is not configured, the host tries to use certain default directories.
On windows, extraction is within %TMPDIR%, which is user specific.
On Unix systems $TMPDIR/.net if set, which may be user specific (ex: MAC)
Otherwise, the extraction directory is within /var/tmp/ or /tmp/ which is common to all users, and may be locked by a specific user on first creation.

This change fixes this issue by defaulting the extraction base directory in Unix systems to
<temp-dir>/.net/<user-ID> , where
<temp-dir>/.net/ has permission 0777, and
<temp-dir>/.net/<user-ID>/ has permission 0700.

Low, scenario is contained, change is small.

dotnet/runtime#2329
swaroop-sridhar added a commit to swaroop-sridhar/core-setup that referenced this issue Feb 28, 2020
…tory

dotnet/runtime#3846

On some Unix systems, multiple users cannot use single-file apps on the same machine.

In .net core 3, single file apps run by extracting the bundled contents to a temp directory.
The extraction directory is machine specific, and can be set through DOTNET_BUNDLE_EXTRACT_BASE_DIR environment variable.

When this setting is not configured, the host tries to use certain default directories.
On windows, extraction is within %TMPDIR%, which is user specific.
On Unix systems $TMPDIR/.net if set, which may be user specific (ex: MAC)
Otherwise, the extraction directory is within /var/tmp/ or /tmp/ which is common to all users, and may be locked by a specific user on first creation.

This change fixes this issue by defaulting the extraction base directory in Unix systems to
<temp-dir>/.net/<user-ID> , where
<temp-dir>/.net/ has permission 0777, and
<temp-dir>/.net/<user-ID>/ has permission 0700.

Low, scenario is contained, change is small.

dotnet/runtime#2329
swaroop-sridhar added a commit to swaroop-sridhar/core-setup that referenced this issue Feb 28, 2020
…tory

** Issue

dotnet/runtime#3846

** Customer Scenario

On some Unix systems, multiple users cannot use single-file apps on the same machine.

** Problem

In .net core 3, single file apps run by extracting the bundled contents to a temp directory.
The extraction directory is machine specific, and can be set through DOTNET_BUNDLE_EXTRACT_BASE_DIR environment variable.

When this setting is not configured, the host tries to use certain default directories.
On windows, extraction is within %TMPDIR%, which is user specific.
On Unix systems $TMPDIR/.net if set, which may be user specific (ex: MAC)
Otherwise, the extraction directory is within /var/tmp/ or /tmp/ which is common to all users, and may be locked by a specific user on first creation.

** Solution

This change fixes this issue by defaulting the extraction base directory in Unix systems to
<temp-dir>/.net/<user-ID> , where
<temp-dir>/.net/ has permission 0777, and
<temp-dir>/.net/<user-ID>/ has permission 0700.

** Risk

Low, scenario is contained, change is small.

** Master Branch

dotnet/runtime#2329
Anipik pushed a commit to dotnet/core-setup that referenced this issue Mar 25, 2020
…tory (#9011)

** Issue

dotnet/runtime#3846

** Customer Scenario

On some Unix systems, multiple users cannot use single-file apps on the same machine.

** Problem

In .net core 3, single file apps run by extracting the bundled contents to a temp directory.
The extraction directory is machine specific, and can be set through DOTNET_BUNDLE_EXTRACT_BASE_DIR environment variable.

When this setting is not configured, the host tries to use certain default directories.
On windows, extraction is within %TMPDIR%, which is user specific.
On Unix systems $TMPDIR/.net if set, which may be user specific (ex: MAC)
Otherwise, the extraction directory is within /var/tmp/ or /tmp/ which is common to all users, and may be locked by a specific user on first creation.

** Solution

This change fixes this issue by defaulting the extraction base directory in Unix systems to
<temp-dir>/.net/<user-ID> , where
<temp-dir>/.net/ has permission 0777, and
<temp-dir>/.net/<user-ID>/ has permission 0700.

** Risk

Low, scenario is contained, change is small.

** Master Branch

dotnet/runtime#2329
@JustArchi
Copy link
Contributor

Hey @swaroop-sridhar, could you let me know if this fix is expected to land in 3.1.4, or maybe has already landed in 3.1.x series? Thank you in advance for answering.

@swaroop-sridhar
Copy link
Contributor Author

This fix is expected in 3.1.4.

@easbarba
Copy link

easbarba commented May 6, 2020

Same here!

@xPaw
Copy link

xPaw commented May 14, 2020

I just tried the 3.1.4 build, and it hasn't really improved the bundle extraction. It still requires the user to set DOTNET_BUNDLE_EXTRACT_BASE_DIR.

Example:

$ ./SteamTokenDumper
realpath(): Permission denied
Failure processing application bundle.
Failed to determine location for extracting embedded files
DOTNET_BUNDLE_EXTRACT_BASE_DIR is not set, and a read-write temp-directory couldn't be created.
A fatal error was encountered. Could not extract contents of the bundle

And if you set DOTNET_BUNDLE_EXTRACT_BASE_DIR to a folder that does not exist, it simply segfaults, without any useful message:

$ export DOTNET_BUNDLE_EXTRACT_BASE_DIR="test"
$ ./SteamTokenDumper
[1]    1203 segmentation fault (core dumped)  ./SteamTokenDumper

After creating the test folder, it will extract and run correctly.

EDIT: After reading through the PR carefully, this change will only work if the tmp/.net currently does not exist on the machine.

@swaroop-sridhar
Copy link
Contributor Author

@xPaw can you please add a few more details:

  • Which OS are you running the app on?
  • The single-file app was rebuilt with 3.1.4 SDK, right?
  • Have you deleted the tmp-directory (/vat/tmp/.net or /tmp/.net) created by apps built with previous SDKs.
  • What is the permissions on /var/tmp/.net/ and /var/tmp/.net/<username>/? I checked on a Ubuntu machine that the permissions are set correctly /var/tmp/.net/ 0x777 and /var/tmp/.net/<username>/ 0x700.

@xPaw
Copy link

xPaw commented May 15, 2020

I built on Windows 10, and then tried to run it on Debian 10 (both a separate server, and WSL). It was built with 3.1.4.

The problem is that /var/tmp/.net already existed from previous apps extracting there, so the permissions were set incorrectly. This is kind of a poor user experience especially when you run apps that were built against earlier SDK version.

Besides, as you can see changing DOTNET_BUNDLE_EXTRACT_BASE_DIR to a folder that does not exist produces a segfault instead of a useful message, or just creating the folder.

@swaroop-sridhar
Copy link
Contributor Author

Thanks for confirming @xPaw. Any colliding directory structures that mask the extraction directory (whether created by an earlier .net host, or via any other process will need to be cleaned up) for the apps to work correctly. Otherwise, a non-colliding path should be specified using DOTNET_BUNDLE_EXTRACT_BASE_DIR.

Did you provide an absolute path in DOTNET_BUNDLE_EXTRACT_BASE_DIR ?
I think the problem is not whether the directory exists or not. But there seems to be a bug when the path doesn't contain a '/' in it. I have filed #36804 for this.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 11, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants