]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Mount encrypted swap partitions via gpt-auto
authorHugo Osvaldo Barrera <hugo@barrera.io>
Sun, 4 Jul 2021 14:30:20 +0000 (16:30 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 8 Jul 2021 09:46:20 +0000 (11:46 +0200)
If the auto-discovered swap partition is LUKS encrypted, decrypt it
automatically.

This aligns with the Discoverable Partitions Specification, though I've
also updated it to explicitly mention that LUKS is now supported here.

Since systemd retries any key already in the kernel keyring, if the swap
partition has the same passphrase as the root partition, the user won't
be prompted a second time for a second passphrase.

See https://github.com/systemd/systemd/issues/20019

docs/DISCOVERABLE_PARTITIONS.md
src/gpt-auto-generator/gpt-auto-generator.c
src/shared/dissect-image.c

index f015578a2d0c37661940739bd10332b501f01892..368cac091fe443f86f6a594e804409731ed46b8d 100644 (file)
@@ -73,7 +73,7 @@ Interface](https://systemd.io/BOOT_LOADER_INTERFACE).
 | `3b8f8425-20e0-4f3b-907f-1a25a76f98e8` | _Server Data Partition_ | Any native, optionally in LUKS | The first partition with this type UUID on the disk containing the root partition is automatically mounted to `/srv/`.  If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/srv`. |
 | `4d21b016-b534-45c2-a9fb-5c16e091fd2d` | _Variable Data Partition_ | Any native, optionally in LUKS | The first partition with this type UUID on the disk containing the root partition is automatically mounted to `/var/` — under the condition that its partition UUID matches the first 128 bit of `HMAC-SHA256(machine-id, 0x4d21b016b53445c2a9fb5c16e091fd2d)` (i.e. the SHA256 HMAC hash of the binary type UUID keyed by the machine ID as read from [`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/machine-id.html). This special requirement is made because `/var/` (unlike the other partition types listed here) is inherently private to a specific installation and cannot possibly be shared between multiple OS installations on the same disk, and thus should be bound to a specific instance of the OS, identified by its machine ID. If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/var`. |
 | `7ec6f557-3bc5-4aca-b293-16ef5df639d1` | _Temporary Data Partition_ | Any native, optionally in LUKS | The first partition with this type UUID on the disk containing the root partition is automatically mounted to `/var/tmp/`.  If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/tmp`. Note that the intended mount point is indeed `/var/tmp/`, not `/tmp/`. The latter is typically maintained in memory via <tt>tmpfs</tt> and does not require a partition on disk. In some cases it might be desirable to make `/tmp/` persistent too, in which case it is recommended to make it a symlink or bind mount to `/var/tmp/`, thus not requiring its own partition type UUID. |
-| `0657fd6d-a4ab-43c4-84e5-0933c84b4f4f` | _Swap_ | Swap | All swap partitions on the disk containing the root partition are automatically enabled. This partition type predates the Discoverable Partitions Specification. |
+| `0657fd6d-a4ab-43c4-84e5-0933c84b4f4f` | _Swap_ | Swap, optionally in LUKS | All swap partitions on the disk containing the root partition are automatically enabled. If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/swap`. This partition type predates the Discoverable Partitions Specification. |
 | `0fc63daf-8483-4772-8e79-3d69d8477de4` | _Generic Linux Data Partitions_ | Any native, optionally in LUKS | No automatic mounting takes place for other Linux data partitions. This partition type should be used for all partitions that carry Linux file systems. The installer needs to mount them explicitly via entries in <tt>/etc/fstab</tt>. Optionally, these partitions may be encrypted with LUKS. This partition type predates the Discoverable Partitions Specification. |
 | `c12a7328-f81f-11d2-ba4b-00a0c93ec93b` | _EFI System Partition_ | VFAT | The ESP used for the current boot is automatically mounted to `/efi/` (or `/boot/` as fallback), unless a different partition is mounted there (possibly via `/etc/fstab`, or because the Extended Boot Loader Partition — see below — exists) or the directory is non-empty on the root disk.  This partition type is defined by the [UEFI Specification](http://www.uefi.org/specifications). |
 | `bc13c2ff-59e6-4262-a352-b275fd6f7172` | _Extended Boot Loader Partition_ | Typically VFAT | The Extended Boot Loader Partition (XBOOTLDR) used for the current boot is automatically mounted to <tt>/boot/</tt>, unless a different partition is mounted there (possibly via <tt>/etc/fstab</tt>) or the directory is non-empty on the root disk. This partition type is defined by the [Boot Loader Specification](https://systemd.io/BOOT_LOADER_SPECIFICATION). |
index 10aa2d98a1e8394e8f702d189d6be8dc969564ef..f5346f49ad1ad91ed1553db54b9b3c53ec9dabfd 100644 (file)
@@ -338,12 +338,14 @@ static int add_partition_mount(
                         SPECIAL_LOCAL_FS_TARGET);
 }
 
-static int add_swap(const char *path) {
-        _cleanup_free_ char *name = NULL, *unit = NULL;
+static int add_swap(DissectedPartition *p) {
+        const char *what;
+        _cleanup_free_ char *name = NULL, *unit = NULL, *crypto_what = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         int r;
 
-        assert(path);
+        assert(p);
+        assert(p->node);
 
         /* Disable the swap auto logic if at least one swap is defined in /etc/fstab, see #6192. */
         r = fstab_has_fstype("swap");
@@ -354,9 +356,17 @@ static int add_swap(const char *path) {
                 return 0;
         }
 
-        log_debug("Adding swap: %s", path);
+        if (streq_ptr(p->fstype, "crypto_LUKS")) {
+                r = add_cryptsetup("swap", p->node, true, true, &crypto_what);
+                if (r < 0)
+                        return r;
+                what = crypto_what;
+        } else
+                what = p->node;
+
+        log_debug("Adding swap: %s", what);
 
-        r = unit_name_from_path(path, ".swap", &name);
+        r = unit_name_from_path(what, ".swap", &name);
         if (r < 0)
                 return log_error_errno(r, "Failed to generate unit name: %m");
 
@@ -374,7 +384,7 @@ static int add_swap(const char *path) {
                 "Description=Swap Partition\n"
                 "Documentation=man:systemd-gpt-auto-generator(8)\n");
 
-        r = generator_write_blockdev_dependency(f, path);
+        r = generator_write_blockdev_dependency(f, what);
         if (r < 0)
                 return r;
 
@@ -382,7 +392,7 @@ static int add_swap(const char *path) {
                 "\n"
                 "[Swap]\n"
                 "What=%s\n",
-                path);
+                what);
 
         r = fflush_and_check(f);
         if (r < 0)
@@ -703,7 +713,7 @@ static int enumerate_partitions(dev_t devnum) {
                 return log_error_errno(r, "Failed to dissect: %m");
 
         if (m->partitions[PARTITION_SWAP].found) {
-                k = add_swap(m->partitions[PARTITION_SWAP].node);
+                k = add_swap(m->partitions + PARTITION_SWAP);
                 if (k < 0)
                         r = k;
         }
index 714baa85723e34d398f16587fd58a05dac1f0cd7..c6542cec7022b26a15d714fefaae0a86a01d7b15 100644 (file)
@@ -1077,7 +1077,6 @@ int dissect_image(
                                         continue;
 
                                 designator = PARTITION_SWAP;
-                                fstype = "swap";
 
                         } else if (sd_id128_equal(type_id, GPT_LINUX_GENERIC)) {