-
Notifications
You must be signed in to change notification settings - Fork 9.7k
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
command: Fix panic for nil credentials source #25110
Conversation
Codecov Report
|
This seems a bit unusual to handle an incorrectly assigned interface value by checking all receivers. If the original bug isn't fixed, any other implementations would also need to check every receiver call. Can we find out where the dynamic type is assigned and check for nil there? |
If we are unable to create a credentials source for some reason, we can rely on the disco object to nil-check it before calling any of its methods. However to do this we must ensure that we pass untyped nil. This commit rearranges the initialization to ensure that this happens. The user-facing bug that triggered this work is that running init when the HOME environment variable is unset would result in a panic on macOS.
be483d8
to
f1f24df
Compare
@jbardin Sorry, I don't completely understand your review comment. Is the change in f1f24df what you were thinking of? If not, could you clarify what you mean by "where the dynamic type is assigned"? Unfortunately I don't think we can run an automated test for this approach, but I've verified it manually locally. |
That's more what I had in mind, but I don't think it prevents the issue, because the dynamic type is added to the interface here: Line 415 in 6fbd394
That function should probably return a |
I'm pretty sure it does prevent the issue (I've locally tested it with a repro for #24520). Note that we're not passing the return value of Changing the return type of Below are some debug lines. (Code which generates these logs) credsSrc, err := credentialsSource(config)
if err != nil {
// Most commands don't actually need credentials, and most situations
// that would get us here would already have been reported by the config
// loading above, so we'll just log this one as an aid to debugging
// in the unlikely event that it _does_ arise.
log.Printf("[WARN] Cannot initialize remote host credentials manager: %s", err)
log.Printf("[DEBUG] credsSrc = %#v, == nil = %v", credsSrc, credsSrc == nil)
}
services := disco.NewWithCredentialsSource(credsSrc)
{
cs := services.CredentialsSource()
log.Printf("[DEBUG] services.CredentialsSource() = %#v, == nil = %v", cs, cs == nil)
} First, the return value from the new
Seems okay so far: it's a typed nil, but comparing it to Now if we immediately call
This should return an |
Sorry, I didn't mean to confuse the issue further; I was thinking you were checking the value was nil rather than the error. You're correct that this will fix the problem. The root of the problem is technically the |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. |
If loading credentials fails, the credentials source can be nil. Calling any of its methods would then result in a panic. This commit adds nil receiver checks to each of the public methods to cope with this case.
The user-facing bug that triggered this work is that running init when the HOME environment variable is unset would result in a panic on macOS.
The
terraform-svchost
package does attempt to nil-check the credentials source before calling its methods. But since the credentials source is an interface, this nil check is always false.I think the correct fix here is for all implementations of the interface to cope with a nil value, rather than trying to use reflection or similar in svchost. Assuming that's agreed-upon, I'll create a PR to svchost to remove these checks.
Fixes #24520.