Loading...
Loading...
### Terraform Version ```shell any ``` ### Terraform Configuration Files In the file /internal/rpcapi/handles.go, method newHandleWithdependency method unlocks only on the success path. If newHandleErrorNoparent is raised, the handleTable's mutex is held forever. This is possible if say openStackConfiguration and ClouseSourceBundle competes concurrently ( improbable but nothing prevents it right now) ### Debug Output The unit test fails with error ``` admin@admins-MacBook-Pro terraform % go test ./internal/rpcapi/... --- FAIL: TestNewHandleWithDependency_NoParentDoesNotLeakLock (2.00s) handles_test.go:48: handleTable.mu was not released after newHandleWithDependency's no-parent error path ā deadlock (mutex leak) FAIL FAIL github.com/hashi ``` ### Expected Behavior Proceeding rpc calls should not be deadlocked. ### Actual Behavior In the file /internal/rpcapi/handles.go, method newHandleWithdependency method unlocks only on the success path. If newHandleErrorNoparent is raised, the handleTable's mutex is held forever. This is possible if say openStackConfiguration and ClouseSourceBundle competes concurrently ( improbable but nothing prevents it right now) The unit test fails with error ``` admin@admins-MacBook-Pro terraform % go test ./internal/rpcapi/... --- FAIL: TestNewHandleWithDependency_NoParentDoesNotLeakLock (2.00s) handles_test.go:48: handleTable.mu was not released after newHandleWithDependency's no-parent error path ā deadlock (mutex leak) FAIL FAIL github.com/hashi ``` ### Steps to Reproduce Providing a reproducible unit test. 1. Please cp the attached file at internal/rpcapi/ with the name handles_test.go 2. execute the test case go test ./internal/rpcapi/... ``` // Copyright IBM Corp. 2014, 2026 // SPDX-License-Identifier: BUSL-1.1 package rpcapi import ( "testing" "time" ) func TestNewHandleWithDependency_NoParentDoesNotLeakLock(t *testing.T) { // similar to serverHandshake in plugin.go tbl := newHandleTable() // Tryong to reproduce a race scenario (eg: closeSourceBundle completes // concurrently with an inflight OpenStackConfiguration) depHnd := newHandle(tbl, "dependency-obj") if err := closeHandle(tbl, depHnd); err != nil { t.Fatalf("close handle errors: %v", err) } _, err := newHandleWithDependency(tbl, "obj", depHnd) if err != newHandleErrorNoParent { t.Fatalf("expected no parent error, got %v", err) } // when no parent error is returned newHandleWithDependency does not release the lock. so calls after would block. // adding a timeout here so as not to break ci. 2secs only. done := make(chan handle[string], 1) go func() { hnd := newHandle(tbl, "another-obj") done <- hnd }() select { case <-done: // mutex was released correctly case <-time.After(2 * time.Second): t.Fatal("handleTable t.mu was not released. deadlocked.") } } ``` ### Additional Context How was this uncovered In the sprit of full transparency : I found this while building my own open source case study [tool](https://github.com/somak2kai/beats) on golang structural fingerprints and potential outliers and I used terraform (among many others oss repos) as test subjects. The method newHandleWithDependency was marked as an outlier compared to its sibling functions , all of whom adopt a lock and defer unlock pattern. The goal of the tool was not to find issues , but was to perform a case study. This particular issue stood out , hence raising it. No personal agenda behind this š ### References _No response_ ### Generative AI / LLM assisted development? The tool that surfaced this issue is deliberately kept semantic unaware, it is open source and can be found at https://github.com/somak2kai/beats However while triaging outliers , a skill is used which is [here](https://github.com/somak2kai/beats/blob/main/beats.plugin/skills/beats-analyze/SKILL.md) which injects semantic context to tool output to identify if an outlier is a potential issue or is minor/explainable/not an issue.
Click on a version to see all relevant bugs
Terraform Integration
Learn more about where this data comes from
BugZero Plan
Streamline upgrades with automated vendor bug scrubs
BugZero Prevent
Wish you caught this bug sooner? Get proactive today.