Commit Graph
4 Commits
Author SHA1 Message Date
Thomas Frauendorfer | Miray Software 42facd5772 gfxmenu/gui: Check printf() format in the gui_progress_bar and gui_label
The gui_progress_bar and gui_label components can display the timeout
value. The format string can be set through a theme file. This patch
adds a validation step to the format string.

If a user loads a theme file into the GRUB without this patch then
a GUI label with the following settings

  + label {
  ...
  id = "__timeout__"
  text = "%s"
  }

will interpret the current timeout value as string pointer and print the
memory at that position on the screen. It is not desired behavior.

Signed-off-by: Thomas Frauendorfer | Miray Software <tf@miray.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-03-02 15:54:20 +01:00
Thomas Frauendorfer | Miray Software 83603bea6c kern/misc: Add function to check printf() format against expected format
The grub_printf_fmt_check() function parses the arguments of an untrusted
printf() format and an expected printf() format and then compares the
arguments counts and arguments types. The arguments count in the untrusted
format string must be less or equal to the arguments count in the expected
format string and both arguments types must match.

To do this the parse_printf_arg_fmt() helper function is extended in the
following way:

  1. Add a return value to report errors to the grub_printf_fmt_check().

  2. Add the fmt_check argument to enable stricter format verification:
     - the function expects that arguments definitions are always
       terminated by a supported conversion specifier.
     - positional parameters, "$", are not allowed, as they cannot be
       validated correctly with the current implementation. For example
       "%s%1$d" would assign the first args entry twice while leaving the
       second one unchanged.
     - Return an error if preallocated space in args is too small and
       allocation fails for the needed size. The grub_printf_fmt_check()
       should verify all arguments. So, if validation is not possible for
       any reason it should return an error.
     This also adds a case entry to handle "%%", which is the escape
     sequence to print "%" character.

  3. Add the max_args argument to check for the maximum allowed arguments
     count in a printf() string. This should be set to the arguments count
     of the expected format. Then the parse_printf_arg_fmt() function will
     return an error if the arguments count is exceeded.

The two additional arguments allow us to use parse_printf_arg_fmt() in
printf() and grub_printf_fmt_check() calls.

When parse_printf_arg_fmt() is used by grub_printf_fmt_check() the
function parse user provided untrusted format string too. So, in
that case it is better to be too strict than too lenient.

Signed-off-by: Thomas Frauendorfer | Miray Software <tf@miray.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-03-02 15:54:20 +01:00
Thomas Frauendorfer | Miray Software 1a2a5aff71 kern/misc: Add STRING type for internal printf() format handling
Set printf() argument type for "%s" to new type STRING. This is in
preparation for a follow up patch to compare a printf() format string
against an expected printf() format string.

For "%s" the corresponding printf() argument is dereferenced as pointer
while all other argument types are defined as integer value. However,
when validating a printf() format it is necessary to differentiate "%s"
from "%p" and other integers. So, let's do that.

Signed-off-by: Thomas Frauendorfer | Miray Software <tf@miray.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-03-02 15:54:20 +01:00
Thomas Frauendorfer | Miray Software 7f11bde314 kern/misc: Split parse_printf_args() into format parsing and va_list handling
This patch is preparing for a follow up patch which will use
the format parsing part to compare the arguments in a printf()
format from an external source against a printf() format with
expected arguments.

Signed-off-by: Thomas Frauendorfer | Miray Software <tf@miray.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-03-02 15:54:19 +01:00