nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

Blame SOURCES/0393-lib-arg-Block-repeated-short-options-that-require-an.patch

b1bcb2
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
b1bcb2
From: Daniel Axtens <dja@axtens.net>
b1bcb2
Date: Fri, 22 Jan 2021 16:07:29 +1100
b1bcb2
Subject: [PATCH] lib/arg: Block repeated short options that require an
b1bcb2
 argument
b1bcb2
b1bcb2
Fuzzing found the following crash:
b1bcb2
b1bcb2
  search -hhhhhhhhhhhhhf
b1bcb2
b1bcb2
We didn't allocate enough option space for 13 hints because the
b1bcb2
allocation code counts the number of discrete arguments (i.e. argc).
b1bcb2
However, the shortopt parsing code will happily keep processing
b1bcb2
a combination of short options without checking if those short
b1bcb2
options require an argument. This means you can easily end writing
b1bcb2
past the allocated option space.
b1bcb2
b1bcb2
This fixes a OOB write which can cause heap corruption.
b1bcb2
b1bcb2
Fixes: CVE-2021-20225
b1bcb2
b1bcb2
Signed-off-by: Daniel Axtens <dja@axtens.net>
b1bcb2
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
b1bcb2
---
b1bcb2
 grub-core/lib/arg.c | 13 +++++++++++++
b1bcb2
 1 file changed, 13 insertions(+)
b1bcb2
b1bcb2
diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c
b1bcb2
index 3288609a5e1..537c5e94b83 100644
b1bcb2
--- a/grub-core/lib/arg.c
b1bcb2
+++ b/grub-core/lib/arg.c
b1bcb2
@@ -299,6 +299,19 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv,
b1bcb2
 		 it can have an argument value.  */
b1bcb2
 	      if (*curshort)
b1bcb2
 		{
b1bcb2
+		  /*
b1bcb2
+		   * Only permit further short opts if this one doesn't
b1bcb2
+		   * require a value.
b1bcb2
+		   */
b1bcb2
+		  if (opt->type != ARG_TYPE_NONE &&
b1bcb2
+		      !(opt->flags & GRUB_ARG_OPTION_OPTIONAL))
b1bcb2
+		    {
b1bcb2
+		      grub_error (GRUB_ERR_BAD_ARGUMENT,
b1bcb2
+				  N_("missing mandatory option for `%s'"),
b1bcb2
+				  opt->longarg);
b1bcb2
+		      goto fail;
b1bcb2
+		    }
b1bcb2
+
b1bcb2
 		  if (parse_option (cmd, opt, 0, usr) || grub_errno)
b1bcb2
 		    goto fail;
b1bcb2
 		}