src/pcrlock/pcrlock.c: Handle empty pcrlock.d directories
authorArnaud Patard <arnaud.patard@collabora.com>
Mon, 8 Jul 2024 13:39:14 +0000 (15:39 +0200)
committerLuca Boccassi <bluca@debian.org>
Thu, 15 Aug 2024 13:04:41 +0000 (14:04 +0100)
Running the following commands:

  # mkdir -p /var/lib/pcrlock.d/123-empty.pcrlock.d
  # /usr/lib/systemd/systemd-pcrlock predict --pcr=1+2+3+4+5+16

Will result in:

...
Floating point exception

Running the following commands:
  # mkdir -p /var/lib/pcrlock.d/123-empty.pcrlock.d
  # /usr/lib/systemd/systemd-pcrlock make-policy --pcr=1+2+3+4+5+16

Will result to this (partial) log:
...
Predicted future PCRs in 133us.
[]
...
Written policy digest 0000000000000000000000000000000000000000000000000000000000000000 to NV index 0x1921da6
...

So, add missing checks to handle gracefully cases where there's no variant
inside the component.

Signed-off-by: Arnaud Patard <arnaud.patard@collabora.com>
(cherry picked from commit e7a93e75219b22424bab95fe45982f5eef21d581)

src/pcrlock/pcrlock.c
test/units/TEST-70-TPM2.pcrlock.sh

index 1716fb32197fd112448ea65f485f05b8ac1034d7..9a7b73fc719fea166c2b920029005a7a40287534 100644 (file)
@@ -1925,6 +1925,9 @@ static int event_log_map_components(EventLog *el) {
                         continue;
                 }
 
+                if (c->n_variants == 0)
+                        log_notice("Component '%s' has no defined variants.", c->id);
+
                 FOREACH_ARRAY(ii, c->variants, c->n_variants) {
                         EventLogComponentVariant *i = *ii;
 
@@ -4060,6 +4063,15 @@ static int event_log_predict_pcrs(
 
         component = ASSERT_PTR(el->components[component_index]);
 
+        if (component->n_variants == 0)
+                return event_log_predict_pcrs(
+                        el,
+                        context,
+                        parent_result,
+                        component_index + 1, /* Next component */
+                        pcr,
+                        path);
+
         FOREACH_ARRAY(ii, component->variants, component->n_variants) {
                 _cleanup_free_ Tpm2PCRPredictionResult *result = NULL;
                 EventLogComponentVariant *variant = *ii;
@@ -4118,7 +4130,9 @@ static ssize_t event_log_calculate_component_combinations(EventLog *el) {
                 /* Overflow check */
                 if (c->n_variants > (size_t) (SSIZE_MAX/count))
                         return log_error_errno(SYNTHETIC_ERRNO(E2BIG), "Too many component combinations.");
-
+                /* If no variant, this will lead to count being 0 and sigfpe */
+                if (c->n_variants == 0)
+                        continue;
                 count *= c->n_variants;
         }
 
index fd51161a7027009664ab30290ee1f8f4707082f9..10fa7a92c27d894b46f33e322c9a71b33e27efb7 100755 (executable)
@@ -89,6 +89,11 @@ systemd-cryptenroll --unlock-key-file=/tmp/pcrlockpwd --tpm2-device=auto --tpm2-
 systemd-cryptsetup attach pcrlock "$img" - tpm2-device=auto,tpm2-pcrlock=/var/lib/systemd/pcrlock.json,headless
 systemd-cryptsetup detach pcrlock
 
+# Ensure systemd-pcrlock not crashing on empty variant directory
+mkdir -p /var/lib/pcrlock.d/123-empty.pcrlock.d
+"$SD_PCRLOCK" predict --pcr="$PCRS"
+rm -rf /var/lib/pcrlock.d/123-empty.pcrlock.d
+
 # Measure something into PCR 16 (the "debug" PCR), which should make the activation fail
 "$SD_PCREXTEND" --pcr=16 test70