Skip to content

Commit bb65d81

Browse files
alecrbrownDaniel Kiper
authored and
Daniel Kiper
committed
cli_lock: Add build option to block command line interface
Add functionality to disable command line interface access and editing of GRUB menu entries if GRUB image is built with --disable-cli. Signed-off-by: Alec Brown <[email protected]> Reviewed-by: Vladimir Serbinenko <[email protected]> Reviewed-by: Daniel Kiper <[email protected]>
1 parent 56e5882 commit bb65d81

File tree

11 files changed

+106
-24
lines changed

11 files changed

+106
-24
lines changed

docs/grub.texi

+4-2
Original file line numberDiff line numberDiff line change
@@ -6422,8 +6422,10 @@ the GRUB command line, edit menu entries, and execute any menu entry. If
64226422
@samp{superusers} is set, then use of the command line and editing of menu
64236423
entries are automatically restricted to superusers. Setting @samp{superusers}
64246424
to empty string effectively disables both access to CLI and editing of menu
6425-
entries. Note: The environment variable needs to be exported to also affect
6426-
the section defined by the @samp{submenu} command (@pxref{submenu}).
6425+
entries. Building a grub image with @samp{--disable-cli} option will also
6426+
disable access to CLI and editing of menu entries, as well as disabling rescue
6427+
mode. Note: The environment variable needs to be exported to also affect the
6428+
section defined by the @samp{submenu} command (@pxref{submenu}).
64276429

64286430
Other users may be allowed to execute specific menu entries by giving a list of
64296431
usernames (as above) using the @option{--users} option to the

grub-core/kern/main.c

+28
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,14 @@
3131
#include <grub/reader.h>
3232
#include <grub/parser.h>
3333
#include <grub/verify.h>
34+
#include <grub/types.h>
3435

3536
#ifdef GRUB_MACHINE_PCBIOS
3637
#include <grub/machine/memory.h>
3738
#endif
3839

40+
static bool cli_disabled = false;
41+
3942
grub_addr_t
4043
grub_modules_get_end (void)
4144
{
@@ -238,6 +241,28 @@ grub_load_normal_mode (void)
238241
grub_command_execute ("normal", 0, 0);
239242
}
240243

244+
bool
245+
grub_is_cli_disabled (void)
246+
{
247+
return cli_disabled;
248+
}
249+
250+
static void
251+
check_is_cli_disabled (void)
252+
{
253+
struct grub_module_header *header;
254+
header = 0;
255+
256+
FOR_MODULES (header)
257+
{
258+
if (header->type == OBJ_TYPE_DISABLE_CLI)
259+
{
260+
cli_disabled = true;
261+
return;
262+
}
263+
}
264+
}
265+
241266
static void
242267
reclaim_module_space (void)
243268
{
@@ -305,6 +330,9 @@ grub_main (void)
305330

306331
grub_boot_time ("After loading embedded modules.");
307332

333+
/* Check if the CLI should be disabled */
334+
check_is_cli_disabled ();
335+
308336
/* It is better to set the root device as soon as possible,
309337
for convenience. */
310338
grub_set_prefix_and_root ();

grub-core/kern/rescue_reader.c

+13
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,19 @@ grub_rescue_read_line (char **line, int cont,
7878
void __attribute__ ((noreturn))
7979
grub_rescue_run (void)
8080
{
81+
/* Stall if the CLI has been disabled */
82+
if (grub_is_cli_disabled ())
83+
{
84+
grub_printf ("Rescue mode has been disabled...\n");
85+
86+
do
87+
{
88+
/* Do not optimize out the loop. */
89+
asm volatile ("");
90+
}
91+
while (1);
92+
}
93+
8194
grub_printf ("Entering rescue mode...\n");
8295

8396
while (1)

grub-core/normal/auth.c

+3
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ grub_auth_check_authentication (const char *userlist)
209209
char entered[GRUB_AUTH_MAX_PASSLEN];
210210
struct grub_auth_user *user;
211211

212+
if (grub_is_cli_disabled ())
213+
return GRUB_ACCESS_DENIED;
214+
212215
grub_memset (login, 0, sizeof (login));
213216

214217
if (is_authenticated (userlist))

grub-core/normal/menu_text.c

+17-14
Original file line numberDiff line numberDiff line change
@@ -178,21 +178,24 @@ command-line or ESC to discard edits and return to the GRUB menu."),
178178

179179
grub_free (msg_translated);
180180

181-
if (nested)
181+
if (!grub_is_cli_disabled ())
182182
{
183-
ret += grub_print_message_indented_real
184-
(_("Press enter to boot the selected OS, "
185-
"`e' to edit the commands before booting "
186-
"or `c' for a command-line. ESC to return previous menu."),
187-
STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
188-
}
189-
else
190-
{
191-
ret += grub_print_message_indented_real
192-
(_("Press enter to boot the selected OS, "
193-
"`e' to edit the commands before booting "
194-
"or `c' for a command-line."),
195-
STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
183+
if (nested)
184+
{
185+
ret += grub_print_message_indented_real
186+
(_("Press enter to boot the selected OS, "
187+
"`e' to edit the commands before booting "
188+
"or `c' for a command-line. ESC to return previous menu."),
189+
STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
190+
}
191+
else
192+
{
193+
ret += grub_print_message_indented_real
194+
(_("Press enter to boot the selected OS, "
195+
"`e' to edit the commands before booting "
196+
"or `c' for a command-line."),
197+
STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
198+
}
196199
}
197200
}
198201
return ret;

include/grub/kernel.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ enum
3030
OBJ_TYPE_PREFIX,
3131
OBJ_TYPE_PUBKEY,
3232
OBJ_TYPE_DTB,
33-
OBJ_TYPE_DISABLE_SHIM_LOCK
33+
OBJ_TYPE_DISABLE_SHIM_LOCK,
34+
OBJ_TYPE_DISABLE_CLI
3435
};
3536

3637
/* The module header. */

include/grub/misc.h

+2
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,8 @@ grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
391391
grub_uint64_t d,
392392
grub_uint64_t *r);
393393

394+
extern bool EXPORT_FUNC(grub_is_cli_disabled) (void);
395+
394396
/* Must match softdiv group in gentpl.py. */
395397
#if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \
396398
(defined(__riscv) && (__riscv_xlen == 32)))

include/grub/util/install.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767
N_("SBAT metadata"), 0 }, \
6868
{ "disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, \
6969
N_("disable shim_lock verifier"), 0 }, \
70+
{ "disable-cli", GRUB_INSTALL_OPTIONS_DISABLE_CLI, 0, 0, \
71+
N_("disabled command line interface access"), 0 }, \
7072
{ "verbose", 'v', 0, 0, \
7173
N_("print verbose messages."), 1 }
7274

@@ -129,7 +131,8 @@ enum grub_install_options {
129131
GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS,
130132
GRUB_INSTALL_OPTIONS_DTB,
131133
GRUB_INSTALL_OPTIONS_SBAT,
132-
GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK
134+
GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK,
135+
GRUB_INSTALL_OPTIONS_DISABLE_CLI
133136
};
134137

135138
extern char *grub_install_source_directory;
@@ -191,7 +194,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
191194
const struct grub_install_image_target_desc *image_target,
192195
int note,
193196
grub_compression_t comp, const char *dtb_file,
194-
const char *sbat_path, const int disable_shim_lock);
197+
const char *sbat_path, const int disable_shim_lock,
198+
const int disable_cli);
195199

196200
const struct grub_install_image_target_desc *
197201
grub_install_get_image_target (const char *arg);

util/grub-install-common.c

+8-3
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ static size_t npubkeys;
466466
static char *sbat;
467467
static int disable_shim_lock;
468468
static grub_compression_t compression;
469+
static int disable_cli;
469470

470471
int
471472
grub_install_parse (int key, char *arg)
@@ -504,6 +505,9 @@ grub_install_parse (int key, char *arg)
504505
case GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK:
505506
disable_shim_lock = 1;
506507
return 1;
508+
case GRUB_INSTALL_OPTIONS_DISABLE_CLI:
509+
disable_cli = 1;
510+
return 1;
507511

508512
case GRUB_INSTALL_OPTIONS_VERBOSITY:
509513
verbosity++;
@@ -679,11 +683,12 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
679683
*p = '\0';
680684

681685
grub_util_info ("grub-mkimage --directory '%s' --prefix '%s' --output '%s'"
682-
" --format '%s' --compression '%s'%s%s%s\n",
686+
" --format '%s' --compression '%s'%s%s%s%s\n",
683687
dir, prefix, outname,
684688
mkimage_target, compnames[compression],
685689
note ? " --note" : "",
686-
disable_shim_lock ? " --disable-shim-lock" : "", s);
690+
disable_shim_lock ? " --disable-shim-lock" : "",
691+
disable_cli ? " --disable-cli" : "", s);
687692
free (s);
688693

689694
tgt = grub_install_get_image_target (mkimage_target);
@@ -694,7 +699,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
694699
modules.entries, memdisk_path,
695700
pubkeys, npubkeys, config_path, tgt,
696701
note, compression, dtb, sbat,
697-
disable_shim_lock);
702+
disable_shim_lock, disable_cli);
698703
while (dc--)
699704
grub_install_pop_module ();
700705
}

util/grub-mkimage.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ static struct argp_option options[] = {
8383
{"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0},
8484
{"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0},
8585
{"disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, N_("disable shim_lock verifier"), 0},
86+
{"disable-cli", GRUB_INSTALL_OPTIONS_DISABLE_CLI, 0, 0, N_("disable command line interface access"), 0},
8687
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
8788
{ 0, 0, 0, 0, 0, 0 }
8889
};
@@ -128,6 +129,7 @@ struct arguments
128129
char *sbat;
129130
int note;
130131
int disable_shim_lock;
132+
int disable_cli;
131133
const struct grub_install_image_target_desc *image_target;
132134
grub_compression_t comp;
133135
};
@@ -239,6 +241,10 @@ argp_parser (int key, char *arg, struct argp_state *state)
239241
arguments->disable_shim_lock = 1;
240242
break;
241243

244+
case GRUB_INSTALL_OPTIONS_DISABLE_CLI:
245+
arguments->disable_cli = 1;
246+
break;
247+
242248
case 'v':
243249
verbosity++;
244250
break;
@@ -325,7 +331,8 @@ main (int argc, char *argv[])
325331
arguments.npubkeys, arguments.config,
326332
arguments.image_target, arguments.note,
327333
arguments.comp, arguments.dtb,
328-
arguments.sbat, arguments.disable_shim_lock);
334+
arguments.sbat, arguments.disable_shim_lock,
335+
arguments.disable_cli);
329336

330337
if (grub_util_file_sync (fp) < 0)
331338
grub_util_error (_("cannot sync `%s': %s"), arguments.output ? : "stdout",

util/mkimage.c

+15-1
Original file line numberDiff line numberDiff line change
@@ -886,7 +886,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
886886
size_t npubkeys, char *config_path,
887887
const struct grub_install_image_target_desc *image_target,
888888
int note, grub_compression_t comp, const char *dtb_path,
889-
const char *sbat_path, int disable_shim_lock)
889+
const char *sbat_path, int disable_shim_lock,
890+
int disable_cli)
890891
{
891892
char *kernel_img, *core_img;
892893
size_t total_module_size, core_size;
@@ -948,6 +949,9 @@ grub_install_generate_image (const char *dir, const char *prefix,
948949
if (disable_shim_lock)
949950
total_module_size += sizeof (struct grub_module_header);
950951

952+
if (disable_cli)
953+
total_module_size += sizeof (struct grub_module_header);
954+
951955
if (config_path)
952956
{
953957
config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1);
@@ -1094,6 +1098,16 @@ grub_install_generate_image (const char *dir, const char *prefix,
10941098
offset += sizeof (*header);
10951099
}
10961100

1101+
if (disable_cli)
1102+
{
1103+
struct grub_module_header *header;
1104+
1105+
header = (struct grub_module_header *) (kernel_img + offset);
1106+
header->type = grub_host_to_target32 (OBJ_TYPE_DISABLE_CLI);
1107+
header->size = grub_host_to_target32 (sizeof (*header));
1108+
offset += sizeof (*header);
1109+
}
1110+
10971111
if (config_path)
10981112
{
10991113
struct grub_module_header *header;

0 commit comments

Comments
 (0)