|
|
bc092b9 |
From 734668238fcc0ef691a080839e04f33854fa133a Mon Sep 17 00:00:00 2001
|
|
|
bc092b9 |
From: Eric Biggers <ebiggers@google.com>
|
|
|
bc092b9 |
Date: Thu, 29 Jun 2017 13:27:49 +0000
|
|
|
63f1a98 |
Subject: [PATCH 043/250] Allow GRUB to mount ext2/3/4 filesystems that have
|
|
|
bc092b9 |
the encryption feature.
|
|
|
bc092b9 |
|
|
|
bc092b9 |
On such a filesystem, inodes may have EXT4_ENCRYPT_FLAG set.
|
|
|
bc092b9 |
For a regular file, this means its contents are encrypted; for a
|
|
|
bc092b9 |
directory, this means the filenames in its directory entries are
|
|
|
bc092b9 |
encrypted; and for a symlink, this means its target is encrypted. Since
|
|
|
bc092b9 |
GRUB cannot decrypt encrypted contents or filenames, just issue an error
|
|
|
bc092b9 |
if it would need to do so. This is sufficient to allow unencrypted boot
|
|
|
bc092b9 |
files to co-exist with encrypted files elsewhere on the filesystem.
|
|
|
bc092b9 |
|
|
|
bc092b9 |
(Note that encrypted regular files and symlinks will not normally be
|
|
|
bc092b9 |
encountered outside an encrypted directory; however, it's possible via
|
|
|
bc092b9 |
hard links, so they still need to be handled.)
|
|
|
bc092b9 |
|
|
|
bc092b9 |
Tested by booting from an ext4 /boot partition on which I had run
|
|
|
bc092b9 |
'tune2fs -O encrypt'. I also verified that the expected error messages
|
|
|
bc092b9 |
are printed when trying to access encrypted directories, files, and
|
|
|
bc092b9 |
symlinks from the GRUB command line. Also ran 'sudo ./grub-fs-tester
|
|
|
bc092b9 |
ext4_encrypt'; note that this requires e2fsprogs v1.43+ and Linux v4.1+.
|
|
|
bc092b9 |
|
|
|
bc092b9 |
Signed-off-by: Eric Biggers <ebiggers@google.com>
|
|
|
bc092b9 |
---
|
|
|
bc092b9 |
grub-core/fs/ext2.c | 23 ++++++++++++++++++++++-
|
|
|
bc092b9 |
tests/ext234_test.in | 1 +
|
|
|
bc092b9 |
tests/util/grub-fs-tester.in | 10 ++++++++++
|
|
|
bc092b9 |
3 files changed, 33 insertions(+), 1 deletion(-)
|
|
|
bc092b9 |
|
|
|
bc092b9 |
diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
|
|
|
ec4acbb |
index cdce63bcc9d..b8ad75a0ff7 100644
|
|
|
bc092b9 |
--- a/grub-core/fs/ext2.c
|
|
|
bc092b9 |
+++ b/grub-core/fs/ext2.c
|
|
|
bc092b9 |
@@ -102,6 +102,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
|
|
bc092b9 |
#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
|
|
|
bc092b9 |
#define EXT4_FEATURE_INCOMPAT_MMP 0x0100
|
|
|
bc092b9 |
#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
|
|
|
bc092b9 |
+#define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000
|
|
|
bc092b9 |
|
|
|
bc092b9 |
/* The set of back-incompatible features this driver DOES support. Add (OR)
|
|
|
bc092b9 |
* flags here as the related features are implemented into the driver. */
|
|
|
bc092b9 |
@@ -109,7 +110,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
|
|
bc092b9 |
| EXT4_FEATURE_INCOMPAT_EXTENTS \
|
|
|
bc092b9 |
| EXT4_FEATURE_INCOMPAT_FLEX_BG \
|
|
|
bc092b9 |
| EXT2_FEATURE_INCOMPAT_META_BG \
|
|
|
bc092b9 |
- | EXT4_FEATURE_INCOMPAT_64BIT)
|
|
|
bc092b9 |
+ | EXT4_FEATURE_INCOMPAT_64BIT \
|
|
|
bc092b9 |
+ | EXT4_FEATURE_INCOMPAT_ENCRYPT)
|
|
|
bc092b9 |
/* List of rationales for the ignored "incompatible" features:
|
|
|
bc092b9 |
* needs_recovery: Not really back-incompatible - was added as such to forbid
|
|
|
bc092b9 |
* ext2 drivers from mounting an ext3 volume with a dirty
|
|
|
bc092b9 |
@@ -138,6 +140,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
|
|
bc092b9 |
#define EXT3_JOURNAL_FLAG_DELETED 4
|
|
|
bc092b9 |
#define EXT3_JOURNAL_FLAG_LAST_TAG 8
|
|
|
bc092b9 |
|
|
|
bc092b9 |
+#define EXT4_ENCRYPT_FLAG 0x800
|
|
|
bc092b9 |
#define EXT4_EXTENTS_FLAG 0x80000
|
|
|
bc092b9 |
|
|
|
bc092b9 |
/* The ext2 superblock. */
|
|
|
bc092b9 |
@@ -706,6 +709,12 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
|
|
|
bc092b9 |
grub_ext2_read_inode (diro->data, diro->ino, &diro->inode);
|
|
|
bc092b9 |
if (grub_errno)
|
|
|
bc092b9 |
return 0;
|
|
|
bc092b9 |
+
|
|
|
bc092b9 |
+ if (diro->inode.flags & grub_cpu_to_le32_compile_time (EXT4_ENCRYPT_FLAG))
|
|
|
bc092b9 |
+ {
|
|
|
bc092b9 |
+ grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "symlink is encrypted");
|
|
|
bc092b9 |
+ return 0;
|
|
|
bc092b9 |
+ }
|
|
|
bc092b9 |
}
|
|
|
bc092b9 |
|
|
|
bc092b9 |
symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1);
|
|
|
bc092b9 |
@@ -749,6 +758,12 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir,
|
|
|
bc092b9 |
return 0;
|
|
|
bc092b9 |
}
|
|
|
bc092b9 |
|
|
|
bc092b9 |
+ if (diro->inode.flags & grub_cpu_to_le32_compile_time (EXT4_ENCRYPT_FLAG))
|
|
|
bc092b9 |
+ {
|
|
|
bc092b9 |
+ grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "directory is encrypted");
|
|
|
bc092b9 |
+ return 0;
|
|
|
bc092b9 |
+ }
|
|
|
bc092b9 |
+
|
|
|
bc092b9 |
/* Search the file. */
|
|
|
bc092b9 |
while (fpos < grub_le_to_cpu32 (diro->inode.size))
|
|
|
bc092b9 |
{
|
|
|
bc092b9 |
@@ -859,6 +874,12 @@ grub_ext2_open (struct grub_file *file, const char *name)
|
|
|
bc092b9 |
goto fail;
|
|
|
bc092b9 |
}
|
|
|
bc092b9 |
|
|
|
bc092b9 |
+ if (fdiro->inode.flags & grub_cpu_to_le32_compile_time (EXT4_ENCRYPT_FLAG))
|
|
|
bc092b9 |
+ {
|
|
|
bc092b9 |
+ err = grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "file is encrypted");
|
|
|
bc092b9 |
+ goto fail;
|
|
|
bc092b9 |
+ }
|
|
|
bc092b9 |
+
|
|
|
bc092b9 |
grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_ext2_inode));
|
|
|
bc092b9 |
grub_free (fdiro);
|
|
|
bc092b9 |
|
|
|
bc092b9 |
diff --git a/tests/ext234_test.in b/tests/ext234_test.in
|
|
|
ec4acbb |
index 892b99cbdf6..4f1eb527eb2 100644
|
|
|
bc092b9 |
--- a/tests/ext234_test.in
|
|
|
bc092b9 |
+++ b/tests/ext234_test.in
|
|
|
bc092b9 |
@@ -30,3 +30,4 @@ fi
|
|
|
bc092b9 |
"@builddir@/grub-fs-tester" ext3
|
|
|
bc092b9 |
"@builddir@/grub-fs-tester" ext4
|
|
|
bc092b9 |
"@builddir@/grub-fs-tester" ext4_metabg
|
|
|
bc092b9 |
+"@builddir@/grub-fs-tester" ext4_encrypt
|
|
|
bc092b9 |
diff --git a/tests/util/grub-fs-tester.in b/tests/util/grub-fs-tester.in
|
|
|
ec4acbb |
index 88cbe7365e9..fd7e0f14b68 100644
|
|
|
bc092b9 |
--- a/tests/util/grub-fs-tester.in
|
|
|
bc092b9 |
+++ b/tests/util/grub-fs-tester.in
|
|
|
bc092b9 |
@@ -156,6 +156,12 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do
|
|
|
bc092b9 |
# Could go further but what's the point?
|
|
|
bc092b9 |
MAXBLKSIZE=$((65536*1024))
|
|
|
bc092b9 |
;;
|
|
|
bc092b9 |
+ xext4_encrypt)
|
|
|
bc092b9 |
+ # OS LIMITATION: Linux currently only allows the 'encrypt' feature
|
|
|
bc092b9 |
+ # in combination with block_size = PAGE_SIZE (4096 bytes on x86).
|
|
|
bc092b9 |
+ MINBLKSIZE=$(getconf PAGE_SIZE)
|
|
|
bc092b9 |
+ MAXBLKSIZE=$MINBLKSIZE
|
|
|
bc092b9 |
+ ;;
|
|
|
bc092b9 |
xext*)
|
|
|
bc092b9 |
MINBLKSIZE=1024
|
|
|
bc092b9 |
if [ $MINBLKSIZE -lt $SECSIZE ]; then
|
|
|
bc092b9 |
@@ -796,6 +802,10 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do
|
|
|
bc092b9 |
MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.ext4" -O meta_bg,^resize_inode -b $BLKSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}"
|
|
|
bc092b9 |
MOUNTFS=ext4
|
|
|
bc092b9 |
;;
|
|
|
bc092b9 |
+ xext4_encrypt)
|
|
|
bc092b9 |
+ MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.ext4" -O encrypt -b $BLKSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}"
|
|
|
bc092b9 |
+ MOUNTFS=ext4
|
|
|
bc092b9 |
+ ;;
|
|
|
bc092b9 |
xext*)
|
|
|
bc092b9 |
MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.$fs" -b $BLKSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}" ;;
|
|
|
bc092b9 |
xxfs)
|
|
|
bc092b9 |
--
|
|
|
63f1a98 |
2.14.3
|
|
|
bc092b9 |
|