Sema: fix UAF in zirClosureGet

Previously if a decl failed its capture scope would be deallocated and
set to undefined which would then lead to invalid dereference in
`zirClosureGet`. To avoid this set the capture scope to a special
failed state and fail the current decl with dependency failure if
the failed state is encountered in `zirClosureGet`.

Closes #12433
Closes #12530
Closes #12593
This commit is contained in:
Veikka Tuominen
2022-09-07 22:05:01 +03:00
parent 37afab2add
commit 99826a2ba8
4 changed files with 70 additions and 1 deletions

View File

@@ -345,6 +345,15 @@ pub const CaptureScope = struct {
/// During sema, this map is backed by the gpa. Once sema completes,
/// it is reallocated using the value_arena.
captures: std.AutoHashMapUnmanaged(Zir.Inst.Index, TypedValue) = .{},
pub fn failed(noalias self: *const @This()) bool {
return self.captures.available == 0 and self.captures.size == std.math.maxInt(u32);
}
pub fn fail(noalias self: *@This()) void {
self.captures.available = 0;
self.captures.size = std.math.maxInt(u32);
}
};
pub const WipCaptureScope = struct {
@@ -383,6 +392,7 @@ pub const WipCaptureScope = struct {
pub fn deinit(noalias self: *@This()) void {
if (!self.finalized) {
self.scope.captures.deinit(self.gpa);
self.scope.fail();
}
self.* = undefined;
}