From: Oldřich Jedlička Date: Sat, 30 Mar 2024 13:45:10 +0000 (+0100) Subject: libblkid: check OPAL lock only when necessary X-Git-Tag: v2.42-start~450^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8049544428c95bba81820d52004557cb4ce38c20;p=thirdparty%2Futil-linux.git libblkid: check OPAL lock only when necessary When the HW OPAL encryption is used, the LUKS2 subsystem field is "HW-OPAL" (see also [1]). Finish the probe only in case LUKS2 is set to use HW OPAL and the disk is locked. [1] https://gitlab.com/cryptsetup/cryptsetup/-/issues/874#note_1838835551 Signed-off-by: Oldřich Jedlička --- diff --git a/libblkid/src/blkidP.h b/libblkid/src/blkidP.h index ea7d81b0c..f71e13cb3 100644 --- a/libblkid/src/blkidP.h +++ b/libblkid/src/blkidP.h @@ -241,6 +241,7 @@ struct blkid_struct_probe #define BLKID_FL_NOSCAN_DEV (1 << 4) /* do not scan this device */ #define BLKID_FL_MODIF_BUFF (1 << 5) /* cached buffers has been modified */ #define BLKID_FL_OPAL_LOCKED (1 << 6) /* OPAL device is locked (I/O errors) */ +#define BLKID_FL_OPAL_CHECKED (1 << 7) /* OPAL lock checked */ /* private per-probing flags */ #define BLKID_PROBE_FL_IGNORE_PT (1 << 1) /* ignore partition table */ diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c index 76905e197..756c7354f 100644 --- a/libblkid/src/probe.c +++ b/libblkid/src/probe.c @@ -603,20 +603,6 @@ static struct blkid_bufinfo *read_buffer(blkid_probe pr, uint64_t real_off, uint * audio+data disks */ if (ret >= 0 || blkid_probe_is_cdrom(pr) || blkdid_probe_is_opal_locked(pr)) errno = 0; -#ifdef HAVE_OPAL_GET_STATUS - else { - struct opal_status st = { }; - - /* If the device is locked with OPAL, we'll fail to read with I/O - * errors when probing deep into the block device. Do not return - * an error, so that we can move on to different types of checks.*/ - ret = ioctl(pr->fd, IOC_OPAL_GET_STATUS, &st); - if (ret == 0 && (st.flags & OPAL_FL_LOCKED)) { - pr->flags |= BLKID_FL_OPAL_LOCKED; - errno = 0; - } - } -#endif return NULL; } @@ -911,6 +897,25 @@ int blkid_probe_is_cdrom(blkid_probe pr) int blkdid_probe_is_opal_locked(blkid_probe pr) { + if (!(pr->flags & BLKID_FL_OPAL_CHECKED)) { + pr->flags |= BLKID_FL_OPAL_CHECKED; + +#ifdef HAVE_OPAL_GET_STATUS + ssize_t ret; + struct opal_status st = { }; + int errsv = errno; + + /* If the device is locked with OPAL, we'll fail to read with I/O + * errors when probing deep into the block device. */ + ret = ioctl(pr->fd, IOC_OPAL_GET_STATUS, &st); + if (ret == 0 && (st.flags & OPAL_FL_LOCKED)) { + pr->flags |= BLKID_FL_OPAL_LOCKED; + } + + errno = errsv; +#endif + } + return (pr->flags & BLKID_FL_OPAL_LOCKED); } diff --git a/libblkid/src/superblocks/luks.c b/libblkid/src/superblocks/luks.c index 1c487f8ff..5ab7e73c9 100644 --- a/libblkid/src/superblocks/luks.c +++ b/libblkid/src/superblocks/luks.c @@ -34,6 +34,8 @@ #define LUKS_MAGIC "LUKS\xba\xbe" #define LUKS_MAGIC_2 "SKUL\xba\xbe" +#define LUKS2_HW_OPAL_SUBSYSTEM "HW-OPAL" + /* Offsets for secondary header (for scan if primary header is corrupted). */ #define LUKS2_HDR2_OFFSETS { 0x04000, 0x008000, 0x010000, 0x020000, \ 0x40000, 0x080000, 0x100000, 0x200000, 0x400000 } @@ -139,12 +141,31 @@ static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag __attribute_ return BLKID_PROBE_NONE; } -static int probe_luks_opal(blkid_probe pr, const struct blkid_idmag *mag) +static int probe_luks_opal(blkid_probe pr, const struct blkid_idmag *mag __attribute__((__unused__))) { + struct luks2_phdr *header; + int version; + + header = (struct luks2_phdr *) blkid_probe_get_buffer(pr, 0, sizeof(struct luks2_phdr)); + if (!header) + return errno ? -errno : BLKID_PROBE_NONE; + + if (!luks_valid(header, LUKS_MAGIC, 0)) + return BLKID_PROBE_NONE; + + version = be16_to_cpu(header->version); + + if (version != 2) + return BLKID_PROBE_NONE; + + if (memcmp(header->subsystem, LUKS2_HW_OPAL_SUBSYSTEM, sizeof(LUKS2_HW_OPAL_SUBSYSTEM)) != 0) + return BLKID_PROBE_NONE; + if (!blkdid_probe_is_opal_locked(pr)) return BLKID_PROBE_NONE; - return probe_luks(pr, mag); + /* Locked drive with LUKS2 HW OPAL encryption, finish probe now */ + return luks_attributes(pr, header, 0); } const struct blkid_idinfo luks_idinfo =