Skip to content

Commit

Permalink
Fix tboot-bless-boot not working with newline from /proc/cmdline
Browse files Browse the repository at this point in the history
  • Loading branch information
jmbaur committed Jun 22, 2024
1 parent 6e11975 commit c73f5d3
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 68 deletions.
1 change: 1 addition & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ pub fn build(b: *std.Build) !void {
.optimize = optimize,
.strip = optimize != std.builtin.OptimizeMode.Debug,
});
tboot_bless_boot.root_module.addImport("clap", clap.module("clap"));
b.installArtifact(tboot_bless_boot);

const tboot_bless_boot_generator = b.addExecutable(.{
Expand Down
6 changes: 3 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions nixos-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ in
};
systemd.generators.tboot-bless-boot-generator = lib.getExe' pkgs.tinybootTools "tboot-bless-boot-generator";
systemd.services.tboot-bless-boot = {
description = "Mark the Current Boot Loader Entry as Good";
description = "Mark the current boot loader entry as good";
documentation = [ "https://github.com/jmbaur/tinyboot" ];
requires = [ "boot-complete.target" ];
conflicts = [ "shutdown.target" ];
Expand All @@ -91,7 +91,7 @@ in
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = "${lib.getExe' pkgs.tinybootTools "tboot-bless-boot"} ${config.boot.loader.efi.efiSysMountPoint} good";
ExecStart = "${lib.getExe' pkgs.tinybootTools "tboot-bless-boot"} --esp-mnt=${config.boot.loader.efi.efiSysMountPoint} good";
};
};
}
Expand Down
2 changes: 1 addition & 1 deletion src/client.zig
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub const Client = struct {
.stream = try std.net.connectUnixSocket("/run/bus"),
.arena = arena,
.writer = std.io.bufferedWriter(std.io.getStdOut().writer()),
.log_file = try std.fs.openFileAbsolute("/run/log", .{}),
.log_file = try std.fs.cwd().openFile("/run/log", .{}),
};
}

Expand Down
4 changes: 2 additions & 2 deletions src/cpio/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,13 @@ pub fn main() !void {
var archive = try CpioArchive.init(arena.allocator());
defer archive.deinit();

var init_file = try std.fs.openFileAbsolute(init, .{});
var init_file = try std.fs.cwd().openFile(init, .{});
defer init_file.close();

var init_source = std.io.StreamSource{ .file = init_file };
try archive.addEntry(&init_source, "./init", .File, 0o755);

var archive_file = try std.fs.createFileAbsolute(outfile, .{});
var archive_file = try std.fs.cwd().createFile(outfile, .{});
defer archive_file.close();

var archive_file_source = std.io.StreamSource{ .file = archive_file };
Expand Down
2 changes: 1 addition & 1 deletion src/log.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub fn initLogger(t: enum {
}) !void {
switch (t) {
.Server => {
log_file = try std.fs.createFileAbsolute("/run/log", .{
log_file = try std.fs.cwd().createFile("/run/log", .{
.truncate = true,
});
},
Expand Down
2 changes: 1 addition & 1 deletion src/runner.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const std = @import("std");
const builtin = @import("builtin");

fn pathExists(p: []const u8) bool {
std.fs.accessAbsolute(p, .{}) catch {
std.fs.cwd().access(p, .{}) catch {
return false;
};

Expand Down
6 changes: 3 additions & 3 deletions src/tboot-bless-boot-generator.zig
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn main() !void {
return;
}

var kernel_cmdline_file = try std.fs.openFileAbsolute("/proc/cmdline", .{});
var kernel_cmdline_file = try std.fs.cwd().openFile("/proc/cmdline", .{});
defer kernel_cmdline_file.close();

const kernel_cmdline = try kernel_cmdline_file.readToEndAlloc(allocator, 1024);
Expand All @@ -43,12 +43,12 @@ pub fn main() !void {
&.{ early_dir, "basic.target.wants" },
);

std.fs.makeDirAbsolute(basic_target_path) catch |err| switch (err) {
std.fs.cwd().makeDir(basic_target_path) catch |err| switch (err) {
error.PathAlreadyExists => {},
else => return err,
};

var basic_target_dir = try std.fs.openDirAbsolute(basic_target_path, .{});
var basic_target_dir = try std.fs.cwd().openDir(basic_target_path, .{});
defer basic_target_dir.close();

try basic_target_dir.symLink(
Expand Down
109 changes: 59 additions & 50 deletions src/tboot-bless-boot.zig
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const std = @import("std");

const clap = @import("clap");

const bls = @import("./boot/bls.zig");

const Error = error{
MissingEfiSysMountPoint,
MissingAction,
InvalidAction,
MissingBlsEntry,
};
Expand All @@ -29,44 +29,29 @@ const Action = enum {

fn markAsGood(
allocator: std.mem.Allocator,
parent_path: []const u8,
parent_dir: std.fs.Dir,
original_entry_filename: []const u8,
bls_entry_file: bls.BlsEntryFile,
) !void {
if (bls_entry_file.tries_left) |tries_left| {
_ = tries_left;

const orig_fullpath = try std.fs.path.join(
allocator,
&.{ parent_path, original_entry_filename },
);

const new_filename = try std.fmt.allocPrint(
allocator,
"{s}.conf",
.{bls_entry_file.name},
);

const new_fullpath = try std.fs.path.join(
allocator,
&.{ parent_path, new_filename },
);

try std.fs.renameAbsolute(orig_fullpath, new_fullpath);
try parent_dir.rename(original_entry_filename, new_filename);
}
}

fn markAsBad(
allocator: std.mem.Allocator,
parent_path: []const u8,
parent_dir: std.fs.Dir,
original_entry_filename: []const u8,
bls_entry_file: bls.BlsEntryFile,
) !void {
const orig_fullpath = try std.fs.path.join(
allocator,
&.{ parent_path, original_entry_filename },
);

const new_filename = b: {
if (bls_entry_file.tries_done) |tries_done| {
break :b try std.fmt.allocPrint(
Expand All @@ -83,28 +68,16 @@ fn markAsBad(
}
};

const new_fullpath = try std.fs.path.join(
allocator,
&.{ parent_path, new_filename },
);

try std.fs.renameAbsolute(orig_fullpath, new_fullpath);
try parent_dir.rename(original_entry_filename, new_filename);
}

fn printStatus(
allocator: std.mem.Allocator,
parent_path: []const u8,
original_entry_filename: []const u8,
bls_entry_file: bls.BlsEntryFile,
) !void {
const orig_fullpath = try std.fs.path.join(
allocator,
&.{ parent_path, original_entry_filename },
);

var stdout = std.io.getStdOut().writer();

try stdout.print("{s}:\n", .{orig_fullpath});
try stdout.print("{s}:\n", .{original_entry_filename});

if (bls_entry_file.tries_left) |tries_left| {
if (tries_left > 0) {
Expand All @@ -114,23 +87,27 @@ fn printStatus(
} else {
try stdout.print("\tentry is bad\n", .{});
}

if (bls_entry_file.tries_done) |tries_done| {
try stdout.print("\t{} tries done\n", .{tries_done});
}
} else {
try stdout.print("\tentry is good\n", .{});
}
}

fn findEntry(
allocator: std.mem.Allocator,
efi_sys_mount_point: []const u8,
esp_mnt: []const u8,
entry_name: []const u8,
action: Action,
) !void {
const entries_path = try std.fs.path.join(
allocator,
&.{ efi_sys_mount_point, "loader", "entries" },
&.{ esp_mnt, "loader", "entries" },
);

var entries_dir = try std.fs.openDirAbsolute(
var entries_dir = try std.fs.cwd().openDir(
entries_path,
.{ .iterate = true },
);
Expand All @@ -151,29 +128,55 @@ fn findEntry(
};

if (std.mem.eql(u8, bls_entry.name, entry_name)) {
switch (action) {
.good => try markAsGood(allocator, entries_path, dir_entry.name, bls_entry),
.bad => try markAsBad(allocator, entries_path, dir_entry.name, bls_entry),
.status => try printStatus(allocator, entries_path, dir_entry.name, bls_entry),
}
return switch (action) {
.good => try markAsGood(allocator, entries_dir, dir_entry.name, bls_entry),
.bad => try markAsBad(allocator, entries_dir, dir_entry.name, bls_entry),
.status => try printStatus(dir_entry.name, bls_entry),
};
}
}

return Error.MissingBlsEntry;
}

pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();

var args = std.process.args();
const params = comptime clap.parseParamsComptime(
\\-h, --help Display this help and exit.
\\--esp-mnt <DIR> UEFI system partition mountpoint (default /boot).
\\<ACTION> Action to take against current boot entry (mark as "good"/"bad", or print "status").
\\
);

const argv0 = args.next().?;
_ = argv0;
const parsers = comptime .{
.ACTION = clap.parsers.string,
.DIR = clap.parsers.string,
};

const stderr = std.io.getStdErr().writer();

const efi_sys_mount_point = args.next() orelse return Error.MissingEfiSysMountPoint;
const action = try Action.fromStr(args.next() orelse return Error.MissingAction);
var diag = clap.Diagnostic{};
var res = clap.parse(clap.Help, &params, &parsers, .{
.diagnostic = &diag,
.allocator = arena.allocator(),
}) catch |err| {
try diag.report(stderr, err);
try clap.usage(stderr, clap.Help, &params);
return;
};
defer res.deinit();

const kernel_cmdline_file = try std.fs.openFileAbsolute("/proc/cmdline", .{});
if (res.args.help != 0) {
return clap.help(std.io.getStdErr().writer(), clap.Help, &params, .{});
}

const esp_mnt = res.args.@"esp-mnt" orelse std.fs.path.sep_str ++ "boot";
const action = if (res.positionals.len > 0) try Action.fromStr(res.positionals[0]) else Action.status;

const kernel_cmdline_file = try std.fs.cwd().openFile("/proc/cmdline", .{});
defer kernel_cmdline_file.close();

const kernel_cmdline = try kernel_cmdline_file.readToEndAlloc(allocator, 1024);
Expand All @@ -184,7 +187,13 @@ pub fn main() !void {
if (std.mem.startsWith(u8, kernel_param, "tboot.bls-entry=")) {
var param_split = std.mem.splitScalar(u8, kernel_param, '=');
_ = param_split.next().?;
break :b param_split.next() orelse return Error.MissingBlsEntry;

// /proc/cmdline contains newline at the end of the file
break :b std.mem.trimRight(
u8,
param_split.next() orelse return Error.MissingBlsEntry,
"\n",
);
}
}

Expand All @@ -193,7 +202,7 @@ pub fn main() !void {

try findEntry(
allocator,
efi_sys_mount_point,
esp_mnt,
tboot_bls_entry,
action,
);
Expand Down
2 changes: 1 addition & 1 deletion src/tboot-loader.zig
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ fn pid1() !void {
defer log.deinitLogger();

const cmdline = cmdline: {
var cmdline_file = try std.fs.openFileAbsolute("/proc/self/cmdline", .{ .mode = .read_only });
var cmdline_file = try std.fs.cwd().openFile("/proc/self/cmdline", .{ .mode = .read_only });
defer cmdline_file.close();
const cmdline_raw = try cmdline_file.readToEndAlloc(allocator, 2048);
defer allocator.free(cmdline_raw);
Expand Down
8 changes: 4 additions & 4 deletions src/tboot-nixos-install.zig
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ fn installGeneration(
}

if (!args.dry_run) {
var entry_file = try std.fs.createFileAbsolute(entry_path, .{});
var entry_file = try std.fs.cwd().createFile(entry_path, .{});
defer entry_file.close();

try entry_file.writeAll(entry_contents);
Expand Down Expand Up @@ -227,7 +227,7 @@ fn cleanupDir(

if (known_files.get(full_path) == null) {
if (!args.dry_run) {
try std.fs.deleteFileAbsolute(full_path);
try std.fs.cwd().deleteFile(full_path);
}
std.log.info("cleaned up {s}", .{full_path});
}
Expand Down Expand Up @@ -319,7 +319,7 @@ pub fn main() !void {
std.log.warn("running a dry run, no filesystem changes will occur", .{});
}

const esp = try std.fs.openDirAbsolute(args.efi_sys_mount_point, .{
const esp = try std.fs.cwd().openDir(args.efi_sys_mount_point, .{
.iterate = true,
});

Expand All @@ -328,7 +328,7 @@ pub fn main() !void {
&args,
);

var nixos_system_profile_dir = try std.fs.openDirAbsolute(
var nixos_system_profile_dir = try std.fs.cwd().openDir(
"/nix/var/nix/profiles",
.{ .iterate = true },
);
Expand Down

0 comments on commit c73f5d3

Please sign in to comment.