aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOldřich Jedlička <oldium.pro@gmail.com>2024-03-30 14:45:10 +0100
committerOldřich Jedlička <oldium.pro@gmail.com>2024-03-30 22:02:33 +0100
commit8049544428c95bba81820d52004557cb4ce38c20 (patch)
treedb70bf9116bbf9354be0d32335c7dc61dcaa53f1
parent49a969dd87090cf0565e5c08036e887d56765353 (diff)
downloadutil-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.h1
-rw-r--r--libblkid/src/probe.c33
-rw-r--r--libblkid/src/superblocks/luks.c25
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 =