Skip to content

Return empty string instead of throwing when getpwuid_r fails unexpectedly - #132396

Open
HarnageaGabriel wants to merge 1 commit into
dotnet:mainfrom
HarnageaGabriel:fix-getusername-passwd-missing
Open

Return empty string instead of throwing when getpwuid_r fails unexpectedly#132396
HarnageaGabriel wants to merge 1 commit into
dotnet:mainfrom
HarnageaGabriel:fix-getusername-passwd-missing

Conversation

@HarnageaGabriel

Copy link
Copy Markdown

Fixes #119216

Problem

GetUserNameFromPasswd's XML doc already documents that it returns an empty string on failure. That contract already holds when /etc/passwd is readable but the current UID isn't present (getpwuid_r returns -1/ENOENT-equivalent → TryGetUserNameFromPasswd returns null).

But when getpwuid_r fails for any other reason — notably when /etc/passwd itself doesn't exist, as can happen in restricted sandboxes/containers — TryGetUserNameFromPasswd threw an IOException instead. That exception propagates up through Environment.UserName and crashes the calling process (e.g. dotnet build, dotnet new) instead of degrading gracefully.

Repro (from the issue)

docker run -it ubuntu:24.04
apt update && apt install -y dotnet-sdk-8.0
rm /etc/passwd
cd /root
dotnet new create console

Fix

src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetPwUid.cs: in TryGetUserNameFromPasswd, the fallback branch after the ERANGE (buffer-too-small) check no longer throws — it now sets username = null and returns true, same as the "current user not found" path, so GetUserNameFromPasswd returns string.Empty instead of propagating the exception. The ERANGE retry-with-larger-buffer behavior is unchanged.

Also removed the now-unused using System.IO;.

Testing

This is a small interop fix in src/libraries/Common (shared source, no dedicated isolated test project); given the size of the dotnet/runtime repo I did not run a full runtime build. I verified the change by inspecting the diff and confirming no other caller relies on the previously-thrown IOException (checked Environment.UserName in Environment.Unix.cs, the only caller).

…tedly

GetUserNameFromPasswd's doc contract already states it returns an empty
string on failure, matching the existing behavior when the current user
has no passwd entry. But any other getpwuid_r error (e.g. ENOENT when
/etc/passwd is missing, as in restricted sandboxes/containers) fell
through to an IOException, crashing callers like Environment.UserName
and, transitively, dotnet build/dotnet new.

Fixes dotnet#119216
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Aug 17, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@HarnageaGabriel

Copy link
Copy Markdown
Author

@dotnet-policy-service agree

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-runtime
See info in area-owners.md if you want to be subscribed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-System.Runtime community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GetUserNameFromPasswd errors instead of returning empty string if /etc/passwd is missing

2 participants