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

