diff options
author | Karel Zak <kzak@redhat.com> | 2024-04-05 09:33:40 +0200 |
---|---|---|
committer | Karel Zak <kzak@redhat.com> | 2024-04-05 09:33:40 +0200 |
commit | 085a313eaed76cc27c36912a81337566f861f3a4 (patch) | |
tree | 721f3aade1ebf28e5ceb3a808c76a6ba5b8f743d | |
parent | 7ff6aec9929a16544a01aa10ad60a2f1f924cd1f (diff) | |
parent | 8049544428c95bba81820d52004557cb4ce38c20 (diff) | |
download | util-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.h | 1 | ||||
-rw-r--r-- | libblkid/src/probe.c | 33 | ||||
-rw-r--r-- | libblkid/src/superblocks/luks.c | 37 | ||||
-rw-r--r-- | libblkid/src/superblocks/superblocks.c | 3 | ||||
-rw-r--r-- | libblkid/src/superblocks/superblocks.h | 1 |
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; |