aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2024-04-05 09:33:40 +0200
committerKarel Zak <kzak@redhat.com>2024-04-05 09:33:40 +0200
commit085a313eaed76cc27c36912a81337566f861f3a4 (patch)
tree721f3aade1ebf28e5ceb3a808c76a6ba5b8f743d
parent7ff6aec9929a16544a01aa10ad60a2f1f924cd1f (diff)
parent8049544428c95bba81820d52004557cb4ce38c20 (diff)
downloadutil-linux-085a313eaed76cc27c36912a81337566f861f3a4.tar.gz
Merge branch 'fix/opal_luks_blkid_scan' of https://github.com/oldium/util-linux
* 'fix/opal_luks_blkid_scan' of https://github.com/oldium/util-linux: libblkid: check OPAL lock only when necessary libblkid: introduce luks opal prober
-rw-r--r--libblkid/src/blkidP.h1
-rw-r--r--libblkid/src/probe.c33
-rw-r--r--libblkid/src/superblocks/luks.c37
-rw-r--r--libblkid/src/superblocks/superblocks.c3
-rw-r--r--libblkid/src/superblocks/superblocks.h1
5 files changed, 61 insertions, 14 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 47df0a93bc..5e7aceb595 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 4623c98fc9..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,6 +141,33 @@ 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 __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;
+
+ /* Locked drive with LUKS2 HW OPAL encryption, finish probe now */
+ return luks_attributes(pr, header, 0);
+}
+
const struct blkid_idinfo luks_idinfo =
{
.name = "crypto_LUKS",
@@ -146,3 +175,11 @@ const struct blkid_idinfo luks_idinfo =
.probefunc = probe_luks,
.magics = BLKID_NONE_MAGIC
};
+
+const struct blkid_idinfo luks_opal_idinfo =
+{
+ .name = "crypto_LUKS",
+ .usage = BLKID_USAGE_CRYPTO,
+ .probefunc = probe_luks_opal,
+ .magics = BLKID_NONE_MAGIC,
+};
diff --git a/libblkid/src/superblocks/superblocks.c b/libblkid/src/superblocks/superblocks.c
index dd1e6dcf31..e89cb598d6 100644
--- a/libblkid/src/superblocks/superblocks.c
+++ b/libblkid/src/superblocks/superblocks.c
@@ -94,6 +94,9 @@ static int blkid_probe_set_usage(blkid_probe pr, int usage);
*/
static const struct blkid_idinfo *idinfos[] =
{
+ /* First, as access to locked OPAL region triggers IO errors */
+ &luks_opal_idinfo,
+
/* RAIDs */
&linuxraid_idinfo,
&ddfraid_idinfo,
diff --git a/libblkid/src/superblocks/superblocks.h b/libblkid/src/superblocks/superblocks.h
index dc669e0fa0..140261eae8 100644
--- a/libblkid/src/superblocks/superblocks.h
+++ b/libblkid/src/superblocks/superblocks.h
@@ -68,6 +68,7 @@ extern const struct blkid_idinfo snapcow_idinfo;
extern const struct blkid_idinfo verity_hash_idinfo;
extern const struct blkid_idinfo integrity_idinfo;
extern const struct blkid_idinfo luks_idinfo;
+extern const struct blkid_idinfo luks_opal_idinfo;
extern const struct blkid_idinfo highpoint37x_idinfo;
extern const struct blkid_idinfo highpoint45x_idinfo;
extern const struct blkid_idinfo squashfs_idinfo;