authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-03-23 03:58:32+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-03-24 18:28:16+00:00
logaf0668d6c2c7696e695cf0553c1ae2d593e9effe
tree8738e4432c42dddcb8005a8e3ab58135424f0fa4
parent879ea2710f1e1bafab1d3e212cbba37aaf6b818d

Build.Cache: fix UAF during `unhit`


1 files changed, 19 insertions(+), 11 deletions(-)

lib/std/Build/Cache.zig+19-11
......@@ -526,7 +526,7 @@ pub const Manifest = struct {
526526 break :f file;
527527 }
528528 const gop = try self.files.getOrPutAdapted(gpa, prefixed_path, FilesAdapter{});
529 errdefer assert(self.files.popOrNull() != null);
529 errdefer _ = self.files.pop();
530530 if (!gop.found_existing) {
531531 gop.key_ptr.* = .{
532532 .prefixed_path = .{
......@@ -633,10 +633,10 @@ pub const Manifest = struct {
633633 self.hash.hasher.update(&bin_digest);
634634
635635 // Remove files not in the initial hash.
636 for (self.files.keys()[input_file_count..]) |*file| {
637 file.deinit(self.cache.gpa);
636 while (self.files.count() != input_file_count) {
637 var file = self.files.pop();
638 file.key.deinit(self.cache.gpa);
638639 }
639 self.files.shrinkRetainingCapacity(input_file_count);
640640
641641 for (self.files.keys()) |file| {
642642 self.hash.hasher.update(&file.bin_digest);
......@@ -736,19 +736,27 @@ pub const Manifest = struct {
736736 const prefixed_path = try self.cache.findPrefix(file_path);
737737 errdefer gpa.free(prefixed_path.sub_path);
738738
739 const new_ch_file = try self.files.addOne(gpa);
740 new_ch_file.* = .{
739 const gop = try self.files.getOrPutAdapted(gpa, prefixed_path, FilesAdapter{});
740 errdefer _ = self.files.pop();
741
742 if (gop.found_existing) {
743 gpa.free(prefixed_path.sub_path);
744 return gop.key_ptr.contents.?;
745 }
746
747 gop.key_ptr.* = .{
741748 .prefixed_path = prefixed_path,
742749 .max_file_size = max_file_size,
743750 .stat = undefined,
744751 .bin_digest = undefined,
745752 .contents = null,
746753 };
747 errdefer self.files.shrinkRetainingCapacity(self.files.entries.len - 1);
748754
749 try self.populateFileHash(new_ch_file);
755 self.files.lockPointers();
756 defer self.files.unlockPointers();
750757
751 return new_ch_file.contents.?;
758 try self.populateFileHash(gop.key_ptr);
759 return gop.key_ptr.contents.?;
752760 }
753761
754762 /// Add a file as a dependency of process being cached, after the initial hash has been
......@@ -765,7 +773,7 @@ pub const Manifest = struct {
765773 errdefer gpa.free(prefixed_path.sub_path);
766774
767775 const gop = try self.files.getOrPutAdapted(gpa, prefixed_path, FilesAdapter{});
768 errdefer assert(self.files.popOrNull() != null);
776 errdefer _ = self.files.pop();
769777
770778 if (gop.found_existing) {
771779 gpa.free(prefixed_path.sub_path);
......@@ -801,7 +809,7 @@ pub const Manifest = struct {
801809 errdefer gpa.free(prefixed_path.sub_path);
802810
803811 const gop = try self.files.getOrPutAdapted(gpa, prefixed_path, FilesAdapter{});
804 errdefer assert(self.files.popOrNull() != null);
812 errdefer _ = self.files.pop();
805813
806814 if (gop.found_existing) {
807815 gpa.free(prefixed_path.sub_path);