diff options
author | Oldřich Jedlička <oldium.pro@gmail.com> | 2024-03-30 14:45:10 +0100 |
---|---|---|
committer | Oldřich Jedlička <oldium.pro@gmail.com> | 2024-03-30 22:02:33 +0100 |
commit | 8049544428c95bba81820d52004557cb4ce38c20 (patch) | |
tree | db70bf9116bbf9354be0d32335c7dc61dcaa53f1 | |
parent | 49a969dd87090cf0565e5c08036e887d56765353 (diff) | |
download | util-linux-8049544428c95bba81820d52004557cb4ce38c20.tar.gz |
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 <oldium.pro@gmail.com>
-rw-r--r-- | libblkid/src/blkidP.h | 1 | ||||
-rw-r--r-- | libblkid/src/probe.c | 33 | ||||
-rw-r--r-- | libblkid/src/superblocks/luks.c | 25 |
3 files changed, 43 insertions, 16 deletions
diff --git a/libblkid/src/blkidP.h b/libblkid/src/blkidP.h index ea7d81b0c5..f71e13cb33 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 76905e1970..756c7354fe 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 1c487f8ff3..5ab7e73c90 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 = |