[libstore]: Fix a heap-use-after-free bug
Motivation
Under high build load, we were seeing the nix daemon segfault around here. Further investigation suggested that this was a heap-use-after-free issue where the initialOutputs field referenced data in an activation frame that had since gone out of scope.
I believe the issue is caused by going through this while loop 3+ times:
- The DerivationBuilder is constructed taking a reference to initialOutputs. The build doesn't complete but hits this continue statement here. Importantly, the DerivationBuilder is stored in the DerivationBuildingGoal
- The number of current builds is greater or equal to the maximum number of builds and we call
co_return tryToBuild()here. Importantly, I believe co_return of this form is implemented like a tail call, so the current tryToBuild activation frame is destroyed and hence initialOutputs referenced by the builder is destroyed too. - Inside builder->startBuild() triggers the heap-use-after-free issue.
There is at least one other way this could be fixed: by deleting this line and instead performing the build with another iteration of the while loop. It seems to me that a less fragile solution is to ensure that the builder doesn't take a reference to any variables in the current activation frame.
Context
Add :+1: to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.