commands/read: Fix an integer overflow when supplying more than 2^31 characters

The grub_getline() function currently has a signed integer variable "i"
that can be overflown when user supplies more than 2^31 characters.
It results in a memory corruption of the allocated line buffer as well
as supplying large negative values to grub_realloc().

Fixes: CVE-2025-0690

Reported-by: Jonathan Bar Or <jonathanbaror@gmail.com>
Signed-off-by: Jonathan Bar Or <jonathanbaror@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
Jonathan Bar Or 2025-01-23 19:17:05 +01:00 committed by Daniel Kiper
parent b970a5ed96
commit dad8f50297

View File

@ -25,6 +25,7 @@
#include <grub/types.h>
#include <grub/extcmd.h>
#include <grub/i18n.h>
#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@ -37,13 +38,14 @@ static const struct grub_arg_option options[] =
static char *
grub_getline (int silent)
{
int i;
grub_size_t i;
char *line;
char *tmp;
int c;
grub_size_t alloc_size;
i = 0;
line = grub_malloc (1 + i + sizeof('\0'));
line = grub_malloc (1 + sizeof('\0'));
if (! line)
return NULL;
@ -59,8 +61,17 @@ grub_getline (int silent)
line[i] = (char) c;
if (!silent)
grub_printf ("%c", c);
i++;
tmp = grub_realloc (line, 1 + i + sizeof('\0'));
if (grub_add (i, 1, &i))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
return NULL;
}
if (grub_add (i, 1 + sizeof('\0'), &alloc_size))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
return NULL;
}
tmp = grub_realloc (line, alloc_size);
if (! tmp)
{
grub_free (line);