forked from pool/grub2
Accepting request 1128487 from home:michael-chang:branches:Base:System
- Fix unattended boot with TPM2 allows downgrading kernel and rootfs, also enhancing the overall security posture (bsc#1216680) * 0001-Improve-TPM-key-protection-on-boot-interruptions.patch * 0002-Restrict-file-access-on-cryptodisk-print.patch * 0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch * 0004-Key-revocation-on-out-of-bound-file-access.patch OBS-URL: https://build.opensuse.org/request/show/1128487 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=477
This commit is contained in:
parent
9cc9bce139
commit
8c3cd1e56a
286
0001-Improve-TPM-key-protection-on-boot-interruptions.patch
Normal file
286
0001-Improve-TPM-key-protection-on-boot-interruptions.patch
Normal file
@ -0,0 +1,286 @@
|
||||
From fe7ed9104cef56f9e532a0c9a7164393d5d69ae1 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 17 Nov 2023 12:32:59 +0800
|
||||
Subject: [PATCH 1/4] Improve TPM key protection on boot interruptions
|
||||
|
||||
The unattended boot process for full disk encryption relies on an
|
||||
authorized TPM policy to ensure the system's integrity before releasing
|
||||
the key to grub. Subsequently, grub assumes responsibility for securing
|
||||
the boot process, directing it towards a trusted default without any
|
||||
expected interruptions. Any interruption during this process indicates
|
||||
potential modification attempts, and releasing the obtained key to the
|
||||
next stage should not occur in such cases.
|
||||
|
||||
This commit addresses a vulnerability associated with interrupted boot
|
||||
processes that could potentially enable malicious modifications to the
|
||||
default or trusted boot target. To reinforce system security, the code
|
||||
has been updated to incorporate measures that discard the TPM protected
|
||||
key in the event of boot interruptions.
|
||||
|
||||
Furthermore, this patch aims to enhance code readability by renaming
|
||||
structures and function names related to cryptographic keys, improving
|
||||
clarity and maintainability.
|
||||
|
||||
By implementing these changes, this enhancement seeks to fortify the
|
||||
protection of TPM keys, thereby ensuring a more robust defense against
|
||||
potential unauthorized modifications during the boot process.
|
||||
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/crypttab.c | 38 ++++++++++++++++++++++++++---------
|
||||
grub-core/disk/cryptodisk.c | 8 +++++++-
|
||||
grub-core/loader/linux.c | 6 +++---
|
||||
grub-core/normal/main.c | 2 +-
|
||||
grub-core/normal/menu.c | 7 +++++++
|
||||
grub-core/normal/menu_entry.c | 2 +-
|
||||
include/grub/crypttab.h | 18 ++++++++++-------
|
||||
7 files changed, 59 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c
|
||||
index c2217ca98..9397bede9 100644
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -9,17 +9,20 @@
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
-struct grub_key_publisher *kpuber;
|
||||
+grub_crypto_key_list_t *cryptokey_lst;
|
||||
|
||||
grub_err_t
|
||||
-grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path)
|
||||
+grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key_len, const char *path, int is_tpmkey)
|
||||
{
|
||||
- struct grub_key_publisher *cur = NULL;
|
||||
+ grub_crypto_key_list_t *cur = NULL;
|
||||
|
||||
- FOR_LIST_ELEMENTS (cur, kpuber)
|
||||
+ FOR_LIST_ELEMENTS (cur, cryptokey_lst)
|
||||
if (grub_uuidcasecmp (cur->name, uuid, sizeof (cur->name)) == 0)
|
||||
break;
|
||||
|
||||
+ if (!cur && !uuid)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
if (!cur)
|
||||
cur = grub_zalloc (sizeof (*cur));
|
||||
if (!cur)
|
||||
@@ -44,21 +47,24 @@ grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len,
|
||||
cur->path = grub_strdup (path);
|
||||
}
|
||||
|
||||
+ if (is_tpmkey >= 0)
|
||||
+ cur->is_tpmkey = is_tpmkey;
|
||||
+
|
||||
if (!cur->name)
|
||||
{
|
||||
cur->name = grub_strdup (uuid);
|
||||
- grub_list_push (GRUB_AS_LIST_P (&kpuber), GRUB_AS_LIST (cur));
|
||||
+ grub_list_push (GRUB_AS_LIST_P (&cryptokey_lst), GRUB_AS_LIST (cur));
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
-grub_initrd_discard_key (void)
|
||||
+grub_cryptokey_discard (void)
|
||||
{
|
||||
- struct grub_key_publisher *cur, *nxt;
|
||||
+ grub_crypto_key_list_t *cur, *nxt;
|
||||
|
||||
- FOR_LIST_ELEMENTS_SAFE (cur, nxt, kpuber)
|
||||
+ FOR_LIST_ELEMENTS_SAFE (cur, nxt, cryptokey_lst)
|
||||
{
|
||||
grub_list_remove (GRUB_AS_LIST (cur));
|
||||
grub_memset (cur->key, 0, cur->key_len);
|
||||
@@ -69,6 +75,20 @@ grub_initrd_discard_key (void)
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+grub_cryptokey_tpmkey_discard (void)
|
||||
+{
|
||||
+ grub_crypto_key_list_t *cur = NULL;
|
||||
+
|
||||
+ FOR_LIST_ELEMENTS (cur, cryptokey_lst)
|
||||
+ if (cur->is_tpmkey)
|
||||
+ break;
|
||||
+
|
||||
+ /* Discard all keys if any of them is tpm */
|
||||
+ if (cur)
|
||||
+ grub_cryptokey_discard();
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **argv)
|
||||
@@ -92,7 +112,7 @@ grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
|
||||
/*FIXME: Validate UUID string*/
|
||||
- return grub_initrd_publish_key (argv[1], NULL, 0, path);
|
||||
+ return grub_cryptokey_add_or_update (argv[1], NULL, 0, path, -1);
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index c79d4125a..d90ca06dc 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1071,6 +1071,9 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
struct cryptodisk_read_hook_ctx read_hook_data = {0};
|
||||
int askpass = 0;
|
||||
char *part = NULL;
|
||||
+#ifndef GRUB_UTIL
|
||||
+ int is_tpmkey = 0;
|
||||
+#endif
|
||||
|
||||
dev = grub_cryptodisk_get_by_source_disk (source);
|
||||
|
||||
@@ -1183,6 +1186,9 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
ret = grub_cryptodisk_insert (dev, name, source);
|
||||
if (ret != GRUB_ERR_NONE)
|
||||
goto error;
|
||||
+#ifndef GRUB_UTIL
|
||||
+ is_tpmkey = 1;
|
||||
+#endif
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
@@ -1244,7 +1250,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
|
||||
#ifndef GRUB_UTIL
|
||||
if (cargs->key_data && dev)
|
||||
- grub_initrd_publish_key (dev->uuid, (const char *)cargs->key_data, cargs->key_len, NULL);
|
||||
+ grub_cryptokey_add_or_update (dev->uuid, (const char *)cargs->key_data, cargs->key_len, NULL, is_tpmkey);
|
||||
#endif
|
||||
if (askpass)
|
||||
{
|
||||
diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
|
||||
index 9ee8f3790..e5e792958 100644
|
||||
--- a/grub-core/loader/linux.c
|
||||
+++ b/grub-core/loader/linux.c
|
||||
@@ -226,13 +226,13 @@ grub_initrd_init (int argc, char *argv[],
|
||||
int i;
|
||||
int newc = 0;
|
||||
struct dir *root = 0;
|
||||
- struct grub_key_publisher *pk;
|
||||
+ grub_crypto_key_list_t *pk;
|
||||
int numkey = 0;
|
||||
|
||||
initrd_ctx->nfiles = 0;
|
||||
initrd_ctx->components = 0;
|
||||
|
||||
- FOR_LIST_ELEMENTS (pk, kpuber)
|
||||
+ FOR_LIST_ELEMENTS (pk, cryptokey_lst)
|
||||
if (pk->key && pk->path)
|
||||
numkey++;
|
||||
|
||||
@@ -305,7 +305,7 @@ grub_initrd_init (int argc, char *argv[],
|
||||
goto overflow;
|
||||
}
|
||||
|
||||
- FOR_LIST_ELEMENTS (pk, kpuber)
|
||||
+ FOR_LIST_ELEMENTS (pk, cryptokey_lst)
|
||||
if (pk->key && pk->path)
|
||||
{
|
||||
grub_initrd_component (pk->key, pk->key_len, pk->path, initrd_ctx);
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
||||
index a3f711d1d..1b426af69 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -479,7 +479,7 @@ grub_cmdline_run (int nested, int force_auth)
|
||||
return;
|
||||
}
|
||||
|
||||
- grub_initrd_discard_key ();
|
||||
+ grub_cryptokey_discard ();
|
||||
grub_normal_reader_init (nested);
|
||||
|
||||
while (1)
|
||||
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
|
||||
index 14b0ab1ec..1df2638d7 100644
|
||||
--- a/grub-core/normal/menu.c
|
||||
+++ b/grub-core/normal/menu.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <grub/script_sh.h>
|
||||
#include <grub/gfxterm.h>
|
||||
#include <grub/dl.h>
|
||||
+#include <grub/crypttab.h>
|
||||
|
||||
/* Time to delay after displaying an error message about a default/fallback
|
||||
entry failing to boot. */
|
||||
@@ -708,6 +709,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
|
||||
if (grub_key_is_interrupt (key))
|
||||
{
|
||||
timeout = -1;
|
||||
+ grub_cryptokey_tpmkey_discard();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -790,6 +792,11 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
|
||||
clear_timeout ();
|
||||
}
|
||||
|
||||
+ /* Timeout is interrupted by external input, Forget tpmkey if timeout
|
||||
+ * is not cut by enter */
|
||||
+ if (c != '\n' && c != '\r')
|
||||
+ grub_cryptokey_tpmkey_discard();
|
||||
+
|
||||
switch (c)
|
||||
{
|
||||
case GRUB_TERM_KEY_HOME:
|
||||
diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
|
||||
index 384ab9ce3..e5ba91ea4 100644
|
||||
--- a/grub-core/normal/menu_entry.c
|
||||
+++ b/grub-core/normal/menu_entry.c
|
||||
@@ -1263,7 +1263,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
||||
return;
|
||||
}
|
||||
|
||||
- grub_initrd_discard_key();
|
||||
+ grub_cryptokey_discard();
|
||||
|
||||
screen = make_screen (entry);
|
||||
if (! screen)
|
||||
diff --git a/include/grub/crypttab.h b/include/grub/crypttab.h
|
||||
index 113c53cfc..f86404686 100644
|
||||
--- a/include/grub/crypttab.h
|
||||
+++ b/include/grub/crypttab.h
|
||||
@@ -4,21 +4,25 @@
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
|
||||
-struct grub_key_publisher
|
||||
+typedef struct grub_crypto_key_list
|
||||
{
|
||||
- struct grub_key_publisher *next;
|
||||
- struct grub_key_publisher **prev;
|
||||
+ struct grub_crypto_key_list *next;
|
||||
+ struct grub_crypto_key_list **prev;
|
||||
char *name; /* UUID */
|
||||
char *path;
|
||||
char *key;
|
||||
grub_size_t key_len;
|
||||
-};
|
||||
+ int is_tpmkey;
|
||||
+} grub_crypto_key_list_t;
|
||||
|
||||
-extern struct grub_key_publisher *EXPORT_VAR (kpuber);
|
||||
+extern grub_crypto_key_list_t *EXPORT_VAR (cryptokey_lst);
|
||||
|
||||
grub_err_t
|
||||
-grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path);
|
||||
+grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key_len, const char *path, int is_tpmkey);
|
||||
|
||||
void
|
||||
-grub_initrd_discard_key (void);
|
||||
+grub_cryptokey_discard (void);
|
||||
+
|
||||
+void
|
||||
+grub_cryptokey_tpmkey_discard (void);
|
||||
#endif /* ! GRUB_CRYPTTAB_HEADER */
|
||||
--
|
||||
2.42.1
|
||||
|
197
0002-Restrict-file-access-on-cryptodisk-print.patch
Normal file
197
0002-Restrict-file-access-on-cryptodisk-print.patch
Normal file
@ -0,0 +1,197 @@
|
||||
From 912384e63c1e3b6aa9d90effb71cd535a17da1e2 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sat, 18 Nov 2023 19:02:31 +0800
|
||||
Subject: [PATCH 2/4] Restrict file access on cryptodisk print
|
||||
|
||||
When the encrypted partition is automatically unlocked by TPM, granting
|
||||
access to the system upon validation of its known good state, there's a
|
||||
potential vulnerability. Grub gains access to file systems that were
|
||||
previously inaccessible to the public, enabling certain commands from
|
||||
the grub console to print content. This arises due to grub lacking
|
||||
restrictions similar to those imposed by password authentication, which
|
||||
typically occurs before privileged access is granted.
|
||||
|
||||
Although the automatic unlocking process ensures system integrity and a
|
||||
secure environment for grub to operate in, it doesn't directly address
|
||||
the issue of authentication for viewing encrypted partition content.
|
||||
|
||||
This commit addresses this security loophole by implementing a file
|
||||
filter upon adding a TPM key. The newly added file filter will
|
||||
specifically verify if the disk is encrypted, denying access and
|
||||
returning an "Access Denied: prohibited to view encrypted data" error
|
||||
message to alert the user.
|
||||
|
||||
Since the policy to filter out unwanted commands from leaking encrypted
|
||||
content is irreversible, it is advisable to make the loaded module
|
||||
persistent to prevent its removal.
|
||||
|
||||
This enhancement aims to bolster security measures and prevent
|
||||
unauthorized access to encrypted data.
|
||||
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/crypttab.c | 35 ++++++++++++++++++++++++++++++++++-
|
||||
grub-core/disk/diskfilter.c | 35 +++++++++++++++++++++++++++++++++++
|
||||
include/grub/disk.h | 10 ++++++++++
|
||||
include/grub/file.h | 1 +
|
||||
4 files changed, 80 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c
|
||||
index 9397bede9..d3acc4b59 100644
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -6,11 +6,39 @@
|
||||
#include <grub/mm.h>
|
||||
#include <grub/list.h>
|
||||
#include <grub/crypttab.h>
|
||||
+#include <grub/file.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
grub_crypto_key_list_t *cryptokey_lst;
|
||||
|
||||
+static grub_file_t
|
||||
+grub_nocat_open (grub_file_t io, enum grub_file_type type)
|
||||
+{
|
||||
+ grub_disk_t disk;
|
||||
+
|
||||
+ /* Network device */
|
||||
+ if (!io->device->disk)
|
||||
+ return io;
|
||||
+
|
||||
+ disk = io->device->disk;
|
||||
+
|
||||
+ if (grub_disk_is_crypto (disk))
|
||||
+ {
|
||||
+ switch (type & GRUB_FILE_TYPE_MASK)
|
||||
+ {
|
||||
+ case GRUB_FILE_TYPE_CAT:
|
||||
+ case GRUB_FILE_TYPE_HEXCAT:
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to view encrypted data"));
|
||||
+ return NULL;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return io;
|
||||
+}
|
||||
+
|
||||
grub_err_t
|
||||
grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key_len, const char *path, int is_tpmkey)
|
||||
{
|
||||
@@ -48,7 +76,11 @@ grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key
|
||||
}
|
||||
|
||||
if (is_tpmkey >= 0)
|
||||
- cur->is_tpmkey = is_tpmkey;
|
||||
+ {
|
||||
+ cur->is_tpmkey = is_tpmkey;
|
||||
+ if (is_tpmkey)
|
||||
+ grub_file_filter_register (GRUB_FILE_FILTER_NOCAT, grub_nocat_open);
|
||||
+ }
|
||||
|
||||
if (!cur->name)
|
||||
{
|
||||
@@ -121,6 +153,7 @@ GRUB_MOD_INIT(crypttab)
|
||||
{
|
||||
cmd = grub_register_command ("crypttab_entry", grub_cmd_crypttab_entry,
|
||||
N_("VOLUME-NAME ENCRYPTED-DEVICE KEY-FILE") , N_("No description"));
|
||||
+ grub_dl_set_persistent (mod);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(crypttab)
|
||||
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
|
||||
index 5c5fabe1a..b0c1c880d 100644
|
||||
--- a/grub-core/disk/diskfilter.c
|
||||
+++ b/grub-core/disk/diskfilter.c
|
||||
@@ -558,6 +558,39 @@ find_lv (const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static int
|
||||
+grub_diskfilter_has_cryptodisk (const struct grub_diskfilter_lv *lv)
|
||||
+{
|
||||
+ struct grub_diskfilter_pv *pv;
|
||||
+
|
||||
+ if (!lv)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (lv->vg->pvs)
|
||||
+ for (pv = lv->vg->pvs; pv; pv = pv->next)
|
||||
+ {
|
||||
+ if (!pv->disk)
|
||||
+ {
|
||||
+ grub_dprintf ("diskfilter", _("Couldn't find physical volume `%s'."
|
||||
+ " Some modules may be missing from core image."),
|
||||
+ pv->name);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ switch (pv->disk->dev->id)
|
||||
+ {
|
||||
+ case GRUB_DISK_DEVICE_CRYPTODISK_ID:
|
||||
+ return 1;
|
||||
+ case GRUB_DISK_DEVICE_DISKFILTER_ID:
|
||||
+ return grub_diskfilter_has_cryptodisk (pv->disk->data);
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_diskfilter_open (const char *name, grub_disk_t disk)
|
||||
{
|
||||
@@ -589,6 +622,8 @@ grub_diskfilter_open (const char *name, grub_disk_t disk)
|
||||
|
||||
disk->total_sectors = lv->size;
|
||||
disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE;
|
||||
+ disk->is_crypto_diskfilter = grub_diskfilter_has_cryptodisk (lv);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/include/grub/disk.h b/include/grub/disk.h
|
||||
index 3b3db6222..63982f16c 100644
|
||||
--- a/include/grub/disk.h
|
||||
+++ b/include/grub/disk.h
|
||||
@@ -147,6 +147,8 @@ struct grub_disk
|
||||
|
||||
/* Device-specific data. */
|
||||
void *data;
|
||||
+
|
||||
+ int is_crypto_diskfilter;
|
||||
};
|
||||
typedef struct grub_disk *grub_disk_t;
|
||||
|
||||
@@ -314,4 +316,12 @@ void grub_mdraid1x_fini (void);
|
||||
void grub_diskfilter_fini (void);
|
||||
#endif
|
||||
|
||||
+static inline int
|
||||
+grub_disk_is_crypto (grub_disk_t disk)
|
||||
+{
|
||||
+ return ((disk->is_crypto_diskfilter ||
|
||||
+ disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) ?
|
||||
+ 1 : 0);
|
||||
+}
|
||||
+
|
||||
#endif /* ! GRUB_DISK_HEADER */
|
||||
diff --git a/include/grub/file.h b/include/grub/file.h
|
||||
index fde58f0fa..fcfd32ce2 100644
|
||||
--- a/include/grub/file.h
|
||||
+++ b/include/grub/file.h
|
||||
@@ -185,6 +185,7 @@ extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook);
|
||||
/* Filters with lower ID are executed first. */
|
||||
typedef enum grub_file_filter_id
|
||||
{
|
||||
+ GRUB_FILE_FILTER_NOCAT,
|
||||
GRUB_FILE_FILTER_VERIFY,
|
||||
GRUB_FILE_FILTER_GZIO,
|
||||
GRUB_FILE_FILTER_XZIO,
|
||||
--
|
||||
2.42.1
|
||||
|
117
0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch
Normal file
117
0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch
Normal file
@ -0,0 +1,117 @@
|
||||
From 6c8d390809956d355fed8bc830f64e86838e3e82 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sat, 18 Nov 2023 21:42:00 +0800
|
||||
Subject: [PATCH 3/4] Restrict 'ls' and auto file completion on cryptodisk
|
||||
print
|
||||
|
||||
The 'ls' command allows file listing, while file completion assists in
|
||||
providing matched file names by partially inputting via the TAB key.
|
||||
Both functionalities should be restricted when the disk is automatically
|
||||
unlocked for the same reasons as highlighted in the previous patch
|
||||
addressing the limitation on file access to the cryptodisk.
|
||||
|
||||
Given that no file is explicitly opened for listing, employing file
|
||||
filters becomes impractical. Consequently, this patch focuses on
|
||||
modifying relevant routines separately to incorporate necessary checks.
|
||||
The objective is to introduce measures that prevent 'ls' and auto file
|
||||
completion from accessing encrypted data when the disk is automatically
|
||||
unlocked.
|
||||
|
||||
By implementing these modifications, any attempt to utilize 'ls' or file
|
||||
completion on the cryptodisk will result in an "Access Denied:
|
||||
prohibited to browse encrypted data" error message, thus effectively
|
||||
alerting the user about the restricted access.
|
||||
|
||||
While protecting content within disk files from viewing is essential,
|
||||
it's equally crucial to restrict access to in-memory content. This
|
||||
includes prohibiting access to the decrypted in-memory copies of disk
|
||||
files.
|
||||
|
||||
This enhancement aims to fortify security protocols by extending
|
||||
restrictions to additional functionalities beyond direct file access.
|
||||
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/ls.c | 8 ++++++++
|
||||
grub-core/commands/minicmd.c | 6 ++++++
|
||||
grub-core/kern/corecmd.c | 8 ++++++++
|
||||
grub-core/normal/completion.c | 8 ++++++++
|
||||
4 files changed, 30 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c
|
||||
index 8e98c73cc..aeb336a73 100644
|
||||
--- a/grub-core/commands/ls.c
|
||||
+++ b/grub-core/commands/ls.c
|
||||
@@ -183,6 +183,14 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
|
||||
if (! dev)
|
||||
goto fail;
|
||||
|
||||
+ if (dev->disk &&
|
||||
+ grub_disk_is_crypto (dev->disk) &&
|
||||
+ grub_file_filters[GRUB_FILE_FILTER_NOCAT])
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
fs = grub_fs_probe (dev);
|
||||
path = grub_strchr (dirname, ')');
|
||||
if (! path)
|
||||
diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c
|
||||
index fa498931e..8f2ac0539 100644
|
||||
--- a/grub-core/commands/minicmd.c
|
||||
+++ b/grub-core/commands/minicmd.c
|
||||
@@ -101,6 +101,12 @@ grub_mini_cmd_dump (struct grub_command *cmd __attribute__ ((unused)),
|
||||
if (argc == 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no address specified");
|
||||
|
||||
+ /* NOCAT filter is applied to prevent cat alike command from revealing file
|
||||
+ * content, the dump command should also be prohibited to revealing memory
|
||||
+ * content as well */
|
||||
+ if (grub_file_filters[GRUB_FILE_FILTER_NOCAT])
|
||||
+ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited by security policy"));
|
||||
+
|
||||
#if GRUB_CPU_SIZEOF_VOID_P == GRUB_CPU_SIZEOF_LONG
|
||||
#define grub_strtoaddr grub_strtoul
|
||||
#else
|
||||
diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c
|
||||
index 62d434ba9..b639bc3ae 100644
|
||||
--- a/grub-core/kern/corecmd.c
|
||||
+++ b/grub-core/kern/corecmd.c
|
||||
@@ -135,6 +135,14 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
|
||||
if (! dev)
|
||||
goto fail;
|
||||
|
||||
+ if (dev->disk &&
|
||||
+ grub_disk_is_crypto (dev->disk) &&
|
||||
+ grub_file_filters[GRUB_FILE_FILTER_NOCAT])
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
fs = grub_fs_probe (dev);
|
||||
path = grub_strchr (argv[0], ')');
|
||||
if (! path)
|
||||
diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c
|
||||
index 18cadfa85..d003ec37d 100644
|
||||
--- a/grub-core/normal/completion.c
|
||||
+++ b/grub-core/normal/completion.c
|
||||
@@ -259,6 +259,14 @@ complete_file (void)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ if (dev->disk &&
|
||||
+ grub_disk_is_crypto (dev->disk) &&
|
||||
+ grub_file_filters[GRUB_FILE_FILTER_NOCAT])
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
fs = grub_fs_probe (dev);
|
||||
if (! fs)
|
||||
{
|
||||
--
|
||||
2.42.1
|
||||
|
91
0004-Key-revocation-on-out-of-bound-file-access.patch
Normal file
91
0004-Key-revocation-on-out-of-bound-file-access.patch
Normal file
@ -0,0 +1,91 @@
|
||||
From 6547d22fc9e20720d1a896be82b2d50d842f86b0 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 20 Nov 2023 09:25:53 +0800
|
||||
Subject: [PATCH 4/4] Key revocation on out of bound file access
|
||||
|
||||
After successful disk unlocking, grub now takes on the responsibility of
|
||||
safeguarding passwords or TPM keys exclusively within authenticated
|
||||
cryptodisk files. Any attempt to access boot-related files outside this
|
||||
trust realm triggers immediate key revocation, preventing potential
|
||||
compromise by out of bound access.
|
||||
|
||||
This patch strengthens security measures by restricting grub's access to
|
||||
system boot files, except for essential internal processes like memdisk
|
||||
and procfs, ensuring key protection against potential breaches due to
|
||||
inadvertent customizations in grub.cfg.
|
||||
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/crypttab.c | 36 +++++++++++++++++++++++++++++++++++
|
||||
include/grub/file.h | 1 +
|
||||
2 files changed, 37 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c
|
||||
index d3acc4b59..e09296c57 100644
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -121,6 +121,41 @@ grub_cryptokey_tpmkey_discard (void)
|
||||
grub_cryptokey_discard();
|
||||
}
|
||||
|
||||
+static grub_file_t
|
||||
+grub_distrust_open (grub_file_t io,
|
||||
+ enum grub_file_type type __attribute__ ((unused)))
|
||||
+{
|
||||
+ grub_disk_t disk = io->device->disk;
|
||||
+
|
||||
+ if (io->device->disk &&
|
||||
+ (io->device->disk->dev->id == GRUB_DISK_DEVICE_MEMDISK_ID
|
||||
+ || io->device->disk->dev->id == GRUB_DISK_DEVICE_PROCFS_ID))
|
||||
+ return io;
|
||||
+
|
||||
+ /* Ensure second stage files is in a protected location or grub won't hand
|
||||
+ * over the key and discards it */
|
||||
+ switch (type & GRUB_FILE_TYPE_MASK)
|
||||
+ {
|
||||
+ case GRUB_FILE_TYPE_ACPI_TABLE:
|
||||
+ case GRUB_FILE_TYPE_CONFIG:
|
||||
+ case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE:
|
||||
+ case GRUB_FILE_TYPE_FONT:
|
||||
+ case GRUB_FILE_TYPE_GRUB_MODULE:
|
||||
+ case GRUB_FILE_TYPE_GRUB_MODULE_LIST:
|
||||
+ case GRUB_FILE_TYPE_LINUX_KERNEL:
|
||||
+ case GRUB_FILE_TYPE_LINUX_INITRD:
|
||||
+ case GRUB_FILE_TYPE_LOADENV:
|
||||
+ case GRUB_FILE_TYPE_THEME:
|
||||
+ if (!disk || !grub_disk_is_crypto (disk))
|
||||
+ grub_cryptokey_discard ();
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return io;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **argv)
|
||||
@@ -153,6 +188,7 @@ GRUB_MOD_INIT(crypttab)
|
||||
{
|
||||
cmd = grub_register_command ("crypttab_entry", grub_cmd_crypttab_entry,
|
||||
N_("VOLUME-NAME ENCRYPTED-DEVICE KEY-FILE") , N_("No description"));
|
||||
+ grub_file_filter_register (GRUB_FILE_FILTER_DISTRUST, grub_distrust_open);
|
||||
grub_dl_set_persistent (mod);
|
||||
}
|
||||
|
||||
diff --git a/include/grub/file.h b/include/grub/file.h
|
||||
index fcfd32ce2..daf23a9c9 100644
|
||||
--- a/include/grub/file.h
|
||||
+++ b/include/grub/file.h
|
||||
@@ -185,6 +185,7 @@ extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook);
|
||||
/* Filters with lower ID are executed first. */
|
||||
typedef enum grub_file_filter_id
|
||||
{
|
||||
+ GRUB_FILE_FILTER_DISTRUST,
|
||||
GRUB_FILE_FILTER_NOCAT,
|
||||
GRUB_FILE_FILTER_VERIFY,
|
||||
GRUB_FILE_FILTER_GZIO,
|
||||
--
|
||||
2.42.1
|
||||
|
@ -1,3 +1,13 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Nov 22 09:25:23 UTC 2023 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix unattended boot with TPM2 allows downgrading kernel and rootfs, also
|
||||
enhancing the overall security posture (bsc#1216680)
|
||||
* 0001-Improve-TPM-key-protection-on-boot-interruptions.patch
|
||||
* 0002-Restrict-file-access-on-cryptodisk-print.patch
|
||||
* 0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch
|
||||
* 0004-Key-revocation-on-out-of-bound-file-access.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Nov 21 06:52:08 UTC 2023 - Michael Chang <mchang@suse.com>
|
||||
|
||||
|
@ -393,6 +393,10 @@ Patch200: 0001-kern-ieee1275-init-Restrict-high-memory-in-presence-.patch
|
||||
Patch201: 0001-fs-xfs-Incorrect-short-form-directory-data-boundary-.patch
|
||||
Patch202: 0002-fs-xfs-Fix-XFS-directory-extent-parsing.patch
|
||||
Patch203: 0003-fs-xfs-add-large-extent-counters-incompat-feature-su.patch
|
||||
Patch204: 0001-Improve-TPM-key-protection-on-boot-interruptions.patch
|
||||
Patch205: 0002-Restrict-file-access-on-cryptodisk-print.patch
|
||||
Patch206: 0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch
|
||||
Patch207: 0004-Key-revocation-on-out-of-bound-file-access.patch
|
||||
|
||||
Requires: gettext-runtime
|
||||
%if 0%{?suse_version} >= 1140
|
||||
|
Loading…
Reference in New Issue
Block a user