From 5ea0e2cc5a4bbb4c1cb2b2ba3636ec1b5268d8b1 Mon Sep 17 00:00:00 2001 From: Matthew Jackson <1085847+MattJackson@users.noreply.github.com> Date: Mon, 29 Jun 2026 19:54:36 -0700 Subject: [PATCH] ld: drive-prep guard (fire only at kind==Unknown) + firmware_unlocker_name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restore ld's drive-prep match guard so the firmware unlocker fires exactly once (at drive-prep, kind==Unknown) and never re-fires during the content-keyed Aacs/Css dispatch — the consumer (libfreemkv) dispatches at three points (init/cert/css) with the appropriate kind. Add firmware_unlocker_name(drive_id) for "is this drive supported?" drive-info display without unlocking. 89 tests. --- src/ld/mod.rs | 17 ++++++++++++----- src/lib.rs | 7 +++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/ld/mod.rs b/src/ld/mod.rs index 353cd7f..5148590 100644 --- a/src/ld/mod.rs +++ b/src/ld/mod.rs @@ -34,6 +34,13 @@ impl Default for LibreDrive { } } +/// The firmware-unlocker name for a drive that has a bundled profile (for +/// drive-info "is this drive supported?" display), or `None`. A pure profile +/// lookup — does NOT touch the drive or unlock anything. +pub(crate) fn firmware_name(id: &DriveId) -> Option<&'static str> { + profile::find_bundled(id).map(|_| "LibreDrive") +} + impl LibreDrive { /// Read the OEM Volume ID via the matched profile's vendor CDB. /// @@ -79,12 +86,12 @@ impl LibreDrive { } impl Unlocker for LibreDrive { - /// Applies when the drive matches a bundled firmware profile. Disc kind is - /// irrelevant — firmware unlock removes bus encryption at the drive for any - /// disc; it runs first, so a profiled drive is unlocked before the cert/CSS - /// unlockers are ever consulted. + /// Firmware unlock is a DRIVE-PREP concern: it runs before the disc kind is + /// probed (`kind == Unknown`) and keys off the drive identity. It must NOT + /// fire during the later content-keyed dispatch (Aacs/Css), or a DVD/Blu-ray + /// in a profiled drive would be re-firmware-unlocked. fn matches(&self, ctx: &UnlockCtx) -> bool { - profile::find_bundled(ctx.drive_id).is_some() + ctx.kind == crate::DiscKind::Unknown && profile::find_bundled(ctx.drive_id).is_some() } /// Firmware-unlock the drive and report its OEM Volume ID. The unlocked drive diff --git a/src/lib.rs b/src/lib.rs index 63e6019..8a8f771 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -114,6 +114,13 @@ pub trait Unlocker: Send + Sync { ) -> std::result::Result; } +/// Name of the firmware unlocker that supports this drive (for drive-info "is +/// this drive supported?" display), or `None`. A pure profile lookup — does NOT +/// touch the drive or unlock anything. +pub fn firmware_unlocker_name(drive_id: &DriveId) -> Option<&'static str> { + ld::firmware_name(drive_id) +} + /// Every unlocker, in dispatch order (firmware → cert → css). This is the ONLY /// place an unlocker is named. Remove one = delete its line here + its module /// dir; the consumer never changes.