diff options
| author | Veikka Tuominen <git@vexu.eu> | 2022-09-07 22:05:01 +0300 |
|---|---|---|
| committer | Veikka Tuominen <git@vexu.eu> | 2022-09-08 00:37:11 +0300 |
| commit | 99826a2ba89ccd80caaa4eeb47c59a71ddfe76b6 (patch) | |
| tree | 1e769aff2edca88474f60f28846da7a4a62e18f0 /src/Module.zig | |
| parent | 37afab2addab5809e1419a09e3be5ea4f3ee5501 (diff) | |
| download | zig-99826a2ba89ccd80caaa4eeb47c59a71ddfe76b6.tar.gz zig-99826a2ba89ccd80caaa4eeb47c59a71ddfe76b6.zip | |
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
Diffstat (limited to 'src/Module.zig')
| -rw-r--r-- | src/Module.zig | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/src/Module.zig b/src/Module.zig index 3ae6c48edd..ea89225537 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -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; } |
