-
Notifications
You must be signed in to change notification settings - Fork 18k
os/user: Lookup not returning UnknownUserError for unknown user when CGO_ENABLED=1 #67912
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
Comments
Similar Issues
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.) |
Note that I looked at all of those "similar issues", but I think this is different from all of them. The closest is #25973, but it's a bit hard to tell, and that was closed quickly by the creator with "I was doing something wrong" and no further info. |
Prior art outside golang: The link to Ruby implementation from the above: |
@kortschak helped me work through this on Gophers Slack.
So we should be checking the return value (error number) against ENOENT, probably in I still don't know what's different about my machine than my colleague's. Maybe a different For reference, here's a little C program that Dan wrote -- it reproduces this issue on my machine.
I'll try to put up a Go change to fix this. |
Thanks @dimaqq, that Crystal issue looks like exactly the same problem. |
Per golang/go#67912, under some circumstances (on my machine) user.Lookup isn't returning UnknownUserError when it should.
Change https://go.dev/cl/591555 mentions this issue: |
#427) Per golang/go#67912, under some circumstances (on my machine) user.Lookup isn't returning UnknownUserError when it should. So before this fix I get the following test failures: ``` $ go test ./internals/osutil ... FAIL: user_test.go:44: userSuite.TestRealUser user_test.go:71: c.Assert(err, check.IsNil) ... value *errors.errorString = &errors.errorString{s:"user: lookup username guy: no such file or directory"} ("user: lookup username guy: no such file or directory") ... ``` And: ``` $ go test ./internals/daemon ... ---------------------------------------------------------------------- FAIL: api_files_test.go:1128: filesSuite.TestWriteErrors api_files_test.go:1195: checkFileResult(c, r.Result[4], pathUserNotFound, "generic-file-error", ".*unknown user.*") api_files_test.go:273: c.Check(r.Error.Message, Matches, errorMsg) ... value string = "cannot look up user and group: user: lookup username user-not-found: no such file or directory" ... regex string = ".*unknown user.*" api_files_test.go:1196: checkFileResult(c, r.Result[5], pathGroupNotFound, "generic-file-error", ".*unknown group.*") api_files_test.go:273: c.Check(r.Error.Message, Matches, errorMsg) ... value string = "cannot look up user and group: user: lookup groupname group-not-found: no such file or directory" ... regex string = ".*unknown group.*" ... ```
A colleague and I got to the bottom of why/when this is happening. On my machine, for whatever reason (on a relatively fresh Ubuntu 24.04 install), I have the following line in my nsswitch.conf:
It's the |
Go version
go version go1.22.4 linux/amd64
Output of
go env
in your module/workspace:What did you do?
When I call
user.Lookup
on a non-existent user (eg: "baduser"), I expect it to returnuser.UnknownUserError
, but it instead returns a generic non-nil error. I can use the following test program (Go playground link) to easily reproduce this on my system:What did you see happen?
When I run the test script with
CGO_ENABLED=1
(the default on my system) it's instead returning a genericerrors.errorString
(with the message "user: lookup username guy: no such file or directory"):What did you expect to see?
The
user.Lookup
call should return anUnknownUserError
error value, whether or notCGO_ENABLED
is set.When I follow it through in my debugger, it's using the
lookupUser
from cgo_lookup_unix.go, which is calling_C_getpwnam_r
, and that's returning asyscall.Errno
error withENOENT
. Thegetpwnam_r
docs seem to indicate this function can returnENOENT
under such circumstances, so maybe the code should check for that, rather than just thef != 0
test?Why it's changed now on my system, but was working before, I'm not sure -- my colleague, also on Ubuntu 24.04 with the same kernel (Linux 6.8.0-35-generic x86_64) doesn't seem to have this problem. My first thought was a different libc version, but my colleague (who doesn't have this issue) and I both are running the same version -- this one:
Note that I recently upgraded my OS by doing a fresh install of Ubuntu 24.04. When I was on 22.04 I didn't have this problem (though as I noted, my colleague is also on 24.04 and he doesn't have this issue -- it works both with cgo enabled and disabled).
For reference, with an existing user both cgo and non-cgo work fine:
The text was updated successfully, but these errors were encountered: