From 246eebc6cee2cac6941f9acc773ff73baff55d93 Mon Sep 17 00:00:00 2001 From: Nils Date: Fri, 16 Aug 2024 07:28:45 +0000 Subject: [PATCH] Make the footer an arbitrary struct --- src/common.zig | 32 +++++++++++++++++++++++++++----- src/dockerc.zig | 12 ++++++------ src/extract_squashfs.zig | 2 +- src/main.zig | 3 ++- src/replace.zig | 8 ++++++-- src/runtimes.zig | 9 --------- 6 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/common.zig b/src/common.zig index 483ff4d..c724163 100644 --- a/src/common.zig +++ b/src/common.zig @@ -1,6 +1,14 @@ const std = @import("std"); +const builtin = @import("builtin"); const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; +const native_endian = builtin.target.cpu.arch.endian(); + +pub const Footer = extern struct { + offset: u64, + // TODO: make use of this field, currently ignored + require_mapped_uids: bool = false, +}; pub fn mkdtemp(in: []u8) !void { try std.posix.getrandom(in[in.len - 6 ..]); @@ -24,12 +32,26 @@ pub fn extract_file(tmpDir: []const u8, name: []const u8, data: []const u8, allo return path; } -pub fn getOffset(path: []const u8) !u64 { +pub fn getFooter(path: []const u8) !Footer { var file = try std.fs.cwd().openFile(path, .{}); - try file.seekFromEnd(-8); + try file.seekFromEnd(-@sizeOf(Footer)); + + var footer: Footer = undefined; + std.debug.assert(try file.readAll(std.mem.asBytes(&footer)) == @sizeOf(Footer)); + + if (native_endian != std.builtin.Endian.little) { + std.mem.byteSwapAllFields(Footer, footer[0]); + } - var buffer: [8]u8 = undefined; - std.debug.assert(try file.readAll(&buffer) == 8); + return footer; +} + +pub fn writeFooter(file: std.fs.File, footer: Footer) !void { + comptime std.debug.assert(@typeInfo(Footer).Struct.layout != .auto); + + if (native_endian != std.builtin.Endian.little) { + std.mem.byteSwapAllFields(Footer, &footer); + } - return std.mem.readInt(u64, buffer[0..8], std.builtin.Endian.big); + try file.writeAll(std.mem.asBytes(&footer)); } diff --git a/src/dockerc.zig b/src/dockerc.zig index 9b5bc9e..f9b886f 100644 --- a/src/dockerc.zig +++ b/src/dockerc.zig @@ -113,7 +113,6 @@ pub fn main() !void { }); var runtime_content: []const u8 = undefined; - var runtime_content_len_u64: [8]u8 = undefined; if (res.args.arch) |arch| { try skopeo_args.append("--override-arch"); @@ -121,10 +120,8 @@ pub fn main() !void { if (std.mem.eql(u8, arch, "amd64")) { runtime_content = runtime_content_x86_64; - runtime_content_len_u64 = runtime_content_len_u64_x86_64; } else if (std.mem.eql(u8, arch, "arm64")) { runtime_content = runtime_content_aarch64; - runtime_content_len_u64 = runtime_content_len_u64_aarch64; } else { std.debug.panic("unsupported arch: {s}\n", .{arch}); } @@ -132,11 +129,9 @@ pub fn main() !void { switch (builtin.target.cpu.arch) { .x86_64 => { runtime_content = runtime_content_x86_64; - runtime_content_len_u64 = runtime_content_len_u64_x86_64; }, .aarch64 => { runtime_content = runtime_content_aarch64; - runtime_content_len_u64 = runtime_content_len_u64_aarch64; }, else => { std.debug.panic("unsupported arch: {}", .{builtin.target.cpu.arch}); @@ -201,6 +196,11 @@ pub fn main() !void { try file.writeAll(runtime_content); try file.seekFromEnd(0); - try file.writeAll(&runtime_content_len_u64); + + try common.writeFooter(file, common.Footer{ + .offset = runtime_content.len, + .require_mapped_uids = false, + }); + try file.chmod(0o755); } diff --git a/src/extract_squashfs.zig b/src/extract_squashfs.zig index bc63cb1..fc0e669 100644 --- a/src/extract_squashfs.zig +++ b/src/extract_squashfs.zig @@ -8,7 +8,7 @@ pub fn main() !void { if (args.next()) |dockercGeneratedBinary| { if (args.next()) |squashfsOutput| { - const offset = try common.getOffset(dockercGeneratedBinary); + const offset = (try common.getFooter(dockercGeneratedBinary)).offset; const readFile = try std.fs.cwd().openFile(dockercGeneratedBinary, .{}); const writeFile = try std.fs.cwd().createFile(squashfsOutput, .{}); diff --git a/src/main.zig b/src/main.zig index a1d9f41..da5beca 100644 --- a/src/main.zig +++ b/src/main.zig @@ -507,7 +507,8 @@ pub fn main() !u8 { const mount_dir_path = try std.fmt.allocPrintZ(allocator, "{s}/mount", .{temp_dir_path}); defer allocator.free(mount_dir_path); - const offsetArg = try std.fmt.allocPrintZ(allocator, "offset={}", .{try common.getOffset(executable_path)}); + const footer = try common.getFooter(executable_path); + const offsetArg = try std.fmt.allocPrintZ(allocator, "offset={}", .{footer.offset}); defer allocator.free(offsetArg); const args_buf = [_:null]?[*:0]const u8{ "squashfuse", "-o", offsetArg, executable_path, filesystem_bundle_dir_null }; diff --git a/src/replace.zig b/src/replace.zig index a6e6038..cc3f7a4 100644 --- a/src/replace.zig +++ b/src/replace.zig @@ -11,7 +11,7 @@ pub fn main() !void { if (rawPath) |path| { if (rawPathOutput) |path_output| { - const offset = try common.getOffset(path); + const offset = (try common.getFooter(path)).offset; const readFile = try std.fs.cwd().openFile(path, .{}); const writeFile = try std.fs.cwd().createFile(path_output, .{}); @@ -22,7 +22,11 @@ pub fn main() !void { assert(len_to_write == len_written); try writeFile.seekFromEnd(0); - try writeFile.writeAll(&runtimes.runtime_content_len_u64_x86_64); + + try common.writeFooter(writeFile, common.Footer{ + .offset = runtimes.runtime_content_x86_64.len, + }); + try writeFile.chmod(0o755); writeFile.close(); diff --git a/src/runtimes.zig b/src/runtimes.zig index 0594151..dae3ede 100644 --- a/src/runtimes.zig +++ b/src/runtimes.zig @@ -1,13 +1,4 @@ const std = @import("std"); -fn get_runtime_content_len_u64(runtime_content: []const u8) [8]u8 { - var buf: [8]u8 = undefined; - std.mem.writeInt(u64, &buf, runtime_content.len, .big); - return buf; -} - pub const runtime_content_x86_64 = @embedFile("runtime_x86_64"); pub const runtime_content_aarch64 = @embedFile("runtime_aarch64"); - -pub const runtime_content_len_u64_x86_64 = get_runtime_content_len_u64(runtime_content_x86_64); -pub const runtime_content_len_u64_aarch64 = get_runtime_content_len_u64(runtime_content_aarch64);