aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/llvm.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-09-12 13:32:14 -0700
committerAndrew Kelley <andrew@ziglang.org>2023-09-12 20:08:56 -0400
commitcb6201715a7bcae2b278811186afc17a697b25f7 (patch)
tree30db7b0844d0769b87664e83164f734fae1a9627 /src/codegen/llvm.zig
parent7e2b6b0f1bc5877f11c50a217dd88c11481bbad4 (diff)
downloadzig-cb6201715a7bcae2b278811186afc17a697b25f7.tar.gz
zig-cb6201715a7bcae2b278811186afc17a697b25f7.zip
InternPool: prevent anon struct UAF bugs with type safety
Instead of using actual slices for InternPool.Key.AnonStructType, this commit changes to use Slice types instead, which store a long-lived index rather than a pointer. This is a follow-up to 7ef1eb1c27754cb0349fdc10db1f02ff2dddd99b.
Diffstat (limited to 'src/codegen/llvm.zig')
-rw-r--r--src/codegen/llvm.zig25
1 files changed, 17 insertions, 8 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index a2ded0cc8d..7a46472c62 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -2392,7 +2392,7 @@ pub const Object = struct {
comptime assert(struct_layout_version == 2);
var offset: u64 = 0;
- for (tuple.types, tuple.values, 0..) |field_ty, field_val, i| {
+ for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue;
const field_size = field_ty.toType().abiSize(mod);
@@ -2401,7 +2401,7 @@ pub const Object = struct {
offset = field_offset + field_size;
const field_name = if (tuple.names.len != 0)
- ip.stringToSlice(tuple.names[i])
+ ip.stringToSlice(tuple.names.get(ip)[i])
else
try std.fmt.allocPrintZ(gpa, "{d}", .{i});
defer if (tuple.names.len == 0) gpa.free(field_name);
@@ -3325,7 +3325,10 @@ pub const Object = struct {
var offset: u64 = 0;
var big_align: u32 = 0;
- for (anon_struct_type.types, anon_struct_type.values) |field_ty, field_val| {
+ for (
+ anon_struct_type.types.get(ip),
+ anon_struct_type.values.get(ip),
+ ) |field_ty, field_val| {
if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue;
const field_align = field_ty.toType().abiAlignment(mod);
@@ -3874,7 +3877,11 @@ pub const Object = struct {
var offset: u64 = 0;
var big_align: u32 = 0;
var need_unnamed = false;
- for (tuple.types, tuple.values, 0..) |field_ty, field_val, field_index| {
+ for (
+ tuple.types.get(ip),
+ tuple.values.get(ip),
+ 0..,
+ ) |field_ty, field_val, field_index| {
if (field_val != .none) continue;
if (!field_ty.toType().hasRuntimeBitsIgnoreComptime(mod)) continue;
@@ -10537,10 +10544,11 @@ fn llvmField(ty: Type, field_index: usize, mod: *Module) ?LlvmField {
var offset: u64 = 0;
var big_align: u32 = 0;
- const struct_type = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
+ const ip = &mod.intern_pool;
+ const struct_type = switch (ip.indexToKey(ty.toIntern())) {
.anon_struct_type => |tuple| {
var llvm_field_index: c_uint = 0;
- for (tuple.types, tuple.values, 0..) |field_ty, field_val, i| {
+ for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue;
const field_align = field_ty.toType().abiAlignment(mod);
@@ -11118,6 +11126,7 @@ fn isByRef(ty: Type, mod: *Module) bool {
// For tuples and structs, if there are more than this many non-void
// fields, then we make it byref, otherwise byval.
const max_fields_byval = 0;
+ const ip = &mod.intern_pool;
switch (ty.zigTypeTag(mod)) {
.Type,
@@ -11146,10 +11155,10 @@ fn isByRef(ty: Type, mod: *Module) bool {
.Struct => {
// Packed structs are represented to LLVM as integers.
if (ty.containerLayout(mod) == .Packed) return false;
- const struct_type = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
+ const struct_type = switch (ip.indexToKey(ty.toIntern())) {
.anon_struct_type => |tuple| {
var count: usize = 0;
- for (tuple.types, tuple.values) |field_ty, field_val| {
+ for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {
if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue;
count += 1;