diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-09-09 11:43:13 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2021-09-28 17:02:27 +0200 |
commit | 8ee9615e10f449dcabbd5e27c960c26857943832 (patch) | |
tree | a05a03b7b1e87fc16cdc37ca56bb24ddb10f8f26 /src/shared/dissect-image.c | |
parent | 1420cfb4b407b3258fd47614a820b246d1f0163a (diff) | |
download | systemd-8ee9615e10f449dcabbd5e27c960c26857943832.tar.gz |
dissect-image: discover verity signature partitions
This doesn't make use of the discovered partitions yet, but it finds
them at least.
Diffstat (limited to 'src/shared/dissect-image.c')
-rw-r--r-- | src/shared/dissect-image.c | 194 |
1 files changed, 181 insertions, 13 deletions
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 1cfbde683d..af8878f3b8 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -807,6 +807,10 @@ int dissect_image( verity->root_hash && (verity->designator < 0 || verity->designator == PARTITION_ROOT); + m->has_verity_sig = false; /* signature not embedded, must be specified */ + m->verity_sig_ready = m->verity_ready && + verity->root_hash_sig; + options = mount_options_from_designator(mount_options, PARTITION_ROOT); if (options) { o = strdup(options); @@ -982,14 +986,42 @@ int dissect_image( m->has_verity = true; - /* Ignore verity unless a root hash is specified */ - if (sd_id128_is_null(root_verity_uuid) || !sd_id128_equal(root_verity_uuid, id)) + /* If no verity configuration is specified, then don't do verity */ + if (!verity) + continue; + if (verity->designator >= 0 && verity->designator != PARTITION_ROOT) + continue; + + /* If root hash is specified, then ignore everything but the root id */ + if (!sd_id128_is_null(root_verity_uuid) && !sd_id128_equal(root_verity_uuid, id)) continue; designator = PARTITION_ROOT_VERITY; fstype = "DM_verity_hash"; architecture = native_architecture(); rw = false; + + } else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE_VERITY_SIG)) { + + check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); + + if (pflags & GPT_FLAG_NO_AUTO) + continue; + + m->has_verity_sig = true; + + /* If root hash is specified explicitly, then ignore any embedded signature */ + if (!verity) + continue; + if (verity->designator >= 0 && verity->designator != PARTITION_ROOT) + continue; + if (verity->root_hash) + continue; + + designator = PARTITION_ROOT_VERITY_SIG; + fstype = "verity_hash_signature"; + architecture = native_architecture(); + rw = false; } #endif #ifdef GPT_ROOT_SECONDARY @@ -1018,14 +1050,42 @@ int dissect_image( m->has_verity = true; - /* Ignore verity unless root has is specified */ - if (sd_id128_is_null(root_verity_uuid) || !sd_id128_equal(root_verity_uuid, id)) + /* Don't do verity if no verity config is passed in */ + if (!verity) + continue; + if (verity->designator >= 0 && verity->designator != PARTITION_ROOT) + continue; + + /* If root hash is specified, then ignore everything but the root id */ + if (!sd_id128_is_null(root_verity_uuid) && !sd_id128_equal(root_verity_uuid, id)) continue; designator = PARTITION_ROOT_SECONDARY_VERITY; fstype = "DM_verity_hash"; architecture = SECONDARY_ARCHITECTURE; rw = false; + + } else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY_VERITY_SIG)) { + + check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); + + if (pflags & GPT_FLAG_NO_AUTO) + continue; + + m->has_verity_sig = true; + + /* If root hash is specified explicitly, then ignore any embedded signature */ + if (!verity) + continue; + if (verity->designator >= 0 && verity->designator != PARTITION_ROOT) + continue; + if (verity->root_hash) + continue; + + designator = PARTITION_ROOT_SECONDARY_VERITY_SIG; + fstype = "verity_hash_signature"; + architecture = native_architecture(); + rw = false; } #endif #ifdef GPT_USR_NATIVE @@ -1054,14 +1114,41 @@ int dissect_image( m->has_verity = true; - /* Ignore verity unless a usr hash is specified */ - if (sd_id128_is_null(usr_verity_uuid) || !sd_id128_equal(usr_verity_uuid, id)) + if (!verity) + continue; + if (verity->designator >= 0 && verity->designator != PARTITION_USR) + continue; + + /* If usr hash is specified, then ignore everything but the usr id */ + if (!sd_id128_is_null(usr_verity_uuid) && !sd_id128_equal(usr_verity_uuid, id)) continue; designator = PARTITION_USR_VERITY; fstype = "DM_verity_hash"; architecture = native_architecture(); rw = false; + + } else if (sd_id128_equal(type_id, GPT_USR_NATIVE_VERITY_SIG)) { + + check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); + + if (pflags & GPT_FLAG_NO_AUTO) + continue; + + m->has_verity_sig = true; + + /* If usr hash is specified explicitly, then ignore any embedded signature */ + if (!verity) + continue; + if (verity->designator >= 0 && verity->designator != PARTITION_USR) + continue; + if (verity->root_hash) + continue; + + designator = PARTITION_USR_VERITY_SIG; + fstype = "verity_hash_signature"; + architecture = native_architecture(); + rw = false; } #endif #ifdef GPT_USR_SECONDARY @@ -1090,14 +1177,41 @@ int dissect_image( m->has_verity = true; - /* Ignore verity unless usr has is specified */ - if (sd_id128_is_null(usr_verity_uuid) || !sd_id128_equal(usr_verity_uuid, id)) + if (!verity) + continue; + if (verity->designator >= 0 && verity->designator != PARTITION_USR) + continue; + + /* If usr hash is specified, then ignore everything but the root id */ + if (!sd_id128_is_null(usr_verity_uuid) && !sd_id128_equal(usr_verity_uuid, id)) continue; designator = PARTITION_USR_SECONDARY_VERITY; fstype = "DM_verity_hash"; architecture = SECONDARY_ARCHITECTURE; rw = false; + + } else if (sd_id128_equal(type_id, GPT_USR_SECONDARY_VERITY_SIG)) { + + check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); + + if (pflags & GPT_FLAG_NO_AUTO) + continue; + + m->has_verity_sig = true; + + /* If usr hash is specified explicitly, then ignore any embedded signature */ + if (!verity) + continue; + if (verity->designator >= 0 && verity->designator != PARTITION_USR) + continue; + if (verity->root_hash) + continue; + + designator = PARTITION_USR_SECONDARY_VERITY_SIG; + fstype = "verity_hash_signature"; + architecture = native_architecture(); + rw = false; } #endif else if (sd_id128_equal(type_id, GPT_SWAP)) { @@ -1293,10 +1407,13 @@ int dissect_image( * since we never want to mount the secondary arch in this case. */ m->partitions[PARTITION_ROOT_SECONDARY].found = false; m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found = false; + m->partitions[PARTITION_ROOT_SECONDARY_VERITY_SIG].found = false; m->partitions[PARTITION_USR_SECONDARY].found = false; m->partitions[PARTITION_USR_SECONDARY_VERITY].found = false; + m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG].found = false; - } else if (m->partitions[PARTITION_ROOT_VERITY].found) + } else if (m->partitions[PARTITION_ROOT_VERITY].found || + m->partitions[PARTITION_ROOT_VERITY_SIG].found) return -EADDRNOTAVAIL; /* Verity found but no matching rootfs? Something is off, refuse. */ else if (m->partitions[PARTITION_ROOT_SECONDARY].found) { @@ -1308,22 +1425,32 @@ int dissect_image( zero(m->partitions[PARTITION_ROOT_SECONDARY]); m->partitions[PARTITION_ROOT_VERITY] = m->partitions[PARTITION_ROOT_SECONDARY_VERITY]; zero(m->partitions[PARTITION_ROOT_SECONDARY_VERITY]); + m->partitions[PARTITION_ROOT_VERITY_SIG] = m->partitions[PARTITION_ROOT_SECONDARY_VERITY_SIG]; + zero(m->partitions[PARTITION_ROOT_SECONDARY_VERITY_SIG]); m->partitions[PARTITION_USR] = m->partitions[PARTITION_USR_SECONDARY]; zero(m->partitions[PARTITION_USR_SECONDARY]); m->partitions[PARTITION_USR_VERITY] = m->partitions[PARTITION_USR_SECONDARY_VERITY]; zero(m->partitions[PARTITION_USR_SECONDARY_VERITY]); + m->partitions[PARTITION_USR_VERITY_SIG] = m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG]; + zero(m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG]); - } else if (m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found) + } else if (m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found || + m->partitions[PARTITION_ROOT_SECONDARY_VERITY_SIG].found) return -EADDRNOTAVAIL; /* as above */ - if (m->partitions[PARTITION_USR].found) { + /* Hmm, we found a signature partition but no Verity data? Something is off. */ + if (m->partitions[PARTITION_ROOT_VERITY_SIG].found && !m->partitions[PARTITION_ROOT_VERITY].found) + return -EADDRNOTAVAIL; + if (m->partitions[PARTITION_USR].found) { /* Invalidate secondary arch /usr/ if we found the primary arch */ m->partitions[PARTITION_USR_SECONDARY].found = false; m->partitions[PARTITION_USR_SECONDARY_VERITY].found = false; + m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG].found = false; - } else if (m->partitions[PARTITION_USR_VERITY].found) + } else if (m->partitions[PARTITION_USR_VERITY].found || + m->partitions[PARTITION_USR_VERITY_SIG].found) return -EADDRNOTAVAIL; /* as above */ else if (m->partitions[PARTITION_USR_SECONDARY].found) { @@ -1333,10 +1460,17 @@ int dissect_image( zero(m->partitions[PARTITION_USR_SECONDARY]); m->partitions[PARTITION_USR_VERITY] = m->partitions[PARTITION_USR_SECONDARY_VERITY]; zero(m->partitions[PARTITION_USR_SECONDARY_VERITY]); + m->partitions[PARTITION_USR_VERITY_SIG] = m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG]; + zero(m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG]); - } else if (m->partitions[PARTITION_USR_SECONDARY_VERITY].found) + } else if (m->partitions[PARTITION_USR_SECONDARY_VERITY].found || + m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG].found) return -EADDRNOTAVAIL; /* as above */ + /* Hmm, we found a signature partition but no Verity data? Something is off. */ + if (m->partitions[PARTITION_USR_VERITY_SIG].found && !m->partitions[PARTITION_USR_VERITY].found) + return -EADDRNOTAVAIL; + /* If root and /usr are combined then insist that the architecture matches */ if (m->partitions[PARTITION_ROOT].found && m->partitions[PARTITION_USR].found && @@ -1407,6 +1541,9 @@ int dissect_image( return -EADDRNOTAVAIL; if (verity->root_hash) { + /* If we have an explicit root hash and found the partitions for it, then we are ready to use + * Verity, set things up for it */ + if (verity->designator < 0 || verity->designator == PARTITION_ROOT) { if (!m->partitions[PARTITION_ROOT_VERITY].found || !m->partitions[PARTITION_ROOT].found) return -EADDRNOTAVAIL; @@ -1424,6 +1561,16 @@ int dissect_image( m->partitions[PARTITION_USR].rw = false; m->verity_ready = true; } + + if (m->verity_ready) + m->verity_sig_ready = !!verity->root_hash_sig; + + } else if (m->partitions[verity->designator == PARTITION_USR ? PARTITION_USR_VERITY_SIG : PARTITION_ROOT_VERITY_SIG].found) { + + /* If we found an embedded signature partition, we are ready, too. */ + + m->verity_ready = m->verity_sig_ready = true; + m->partitions[verity->designator == PARTITION_USR ? PARTITION_USR : PARTITION_ROOT].rw = false; } } @@ -2901,6 +3048,23 @@ bool dissected_image_verity_ready(const DissectedImage *image, PartitionDesignat return k >= 0 && image->partitions[k].found; } +bool dissected_image_verity_sig_ready(const DissectedImage *image, PartitionDesignator partition_designator) { + PartitionDesignator k; + + assert(image); + + /* Checks if this partition has verity signature data available that we can use. */ + + if (!image->verity_sig_ready) + return false; + + if (image->single_file_system) + return partition_designator == PARTITION_ROOT; + + k = PARTITION_VERITY_SIG_OF(partition_designator); + return k >= 0 && image->partitions[k].found; +} + MountOptions* mount_options_free_all(MountOptions *options) { MountOptions *m; @@ -3014,6 +3178,10 @@ static const char *const partition_designator_table[] = { [PARTITION_ROOT_SECONDARY_VERITY] = "root-secondary-verity", [PARTITION_USR_VERITY] = "usr-verity", [PARTITION_USR_SECONDARY_VERITY] = "usr-secondary-verity", + [PARTITION_ROOT_VERITY_SIG] = "root-verity-sig", + [PARTITION_ROOT_SECONDARY_VERITY_SIG] = "root-secondary-verity-sig", + [PARTITION_USR_VERITY_SIG] = "usr-verity-sig", + [PARTITION_USR_SECONDARY_VERITY_SIG] = "usr-secondary-verity-sig", [PARTITION_TMP] = "tmp", [PARTITION_VAR] = "var", }; |