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/Sema.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/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 8d25a7c93e..15e891ef87 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -5956,7 +5956,6 @@ fn analyzeCall( error.NeededSourceLocation => { _ = sema.inst_map.remove(inst); const decl = sema.mod.declPtr(block.src_decl); - child_block.src_decl = block.src_decl; try sema.analyzeInlineCallArg( block, &child_block, @@ -13740,6 +13739,16 @@ fn zirClosureGet( const tv = while (true) { // Note: We don't need to add a dependency here, because // decls always depend on their lexical parents. + + // Fail this decl if a scope it depended on failed. + if (scope.failed()) { + if (sema.owner_func) |owner_func| { + owner_func.state = .dependency_failure; + } else { + sema.owner_decl.analysis = .dependency_failure; + } + return error.AnalysisFail; + } if (scope.captures.getPtr(inst_data.inst)) |tv| { break tv; } |
