-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Transit: Release locks using defer statements #25336
Transit: Release locks using defer statements #25336
Conversation
- Leverage defer statements to Unlock the fetched policy to avoid issues with forgetting to manually Unlock during each return statement
Build Results: |
CI Results: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems correct
I assume only the changes to builtin/logical/transit/path_sign_verify.go are for fixing the bug and other changes are only for refactoring? |
Hi @mju, yes, the fix could have been to just add the missing .Unlock() in the spot that you had identified, thanks by the way for all the investigation efforts! The issue with that fix is it would be easy in the future to introduce a similar bug here or in the other endpoints, forgetting to call Unlock(). If you look at the PR that I had introduced the issue, I just moved the check location and missed the newly required call. This is a little larger of a fix to prevent a similar issue from occurring in the future across different endpoints of forgetting to explicitly call Unlock(). |
I've been thinking about how to phrase my concerns about how read-write locks are used in the transit code and how to make it better over the past few days. Not as a criticism, but I do think it's better if you can spend days or weeks re-organizing the code. It's way too easy for people to make a mistake modifying this code. It's very difficult to have tests that will warn you about the potential mistakes. The problem, I think, is that the
GetPolicy() can conditionally return with a write lock acquired. and the caller can then conditionally obtain a read lock on its own. As a result, now the caller needs to defer Unlock
It's very easy for a developer to come in and add one single line to cause a deadlock again down the road. I am not sure if I am qualified to suggest a fix here. I however feel it'd be way easier if in the code You can also use a queue (a channel would do?) to take the read and write operations, and make sure there You do kind of have this code structure already as in lock_manager.go. It's just the "queuing" part leaked |
@mju Completely agreed on the points you have raised. We do have an issue raised for this internally to evaluate how to simplify this code. Obviously for a bugfix, that was going to be backported across stable releases, I didn't want to refactor the code to that degree. At this point though I can't say when we would get to it, but it certainly is on our radar. |
* Transit: Release locks using defer statements - Leverage defer statements to Unlock the fetched policy to avoid issues with forgetting to manually Unlock during each return statement * Add cl
* Transit: Release locks using defer statements - Leverage defer statements to Unlock the fetched policy to avoid issues with forgetting to manually Unlock during each return statement * Add cl
Fixes: #25325