mirror of
https://xff.cz/git/u-boot/
synced 2025-09-21 18:42:07 +02:00
bootstage: Fix out-of-bounds read in reloc_bootstage()
bootstage_get_size() returns the total size of the data structure including associated records. When copying from gd->bootstage, only the allocation size of gd->bootstage must be used. Otherwise too much memory is copied. This bug caused no harm so far because gd->new_bootstage is always large enough and reading beyond the allocation length of gd->bootstage caused no problem due to the U-Boot memory layout. Fix by using the correct size and perform the initial copy directly in bootstage_relocate() to have the whole relocation process in the same function. Signed-off-by: Richard Weinberger <richard@nod.at> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
committed by
Tom Rini
parent
faf73fb70d
commit
1779a58c66
@@ -684,13 +684,7 @@ static int reloc_bootstage(void)
|
|||||||
if (gd->flags & GD_FLG_SKIP_RELOC)
|
if (gd->flags & GD_FLG_SKIP_RELOC)
|
||||||
return 0;
|
return 0;
|
||||||
if (gd->new_bootstage) {
|
if (gd->new_bootstage) {
|
||||||
int size = bootstage_get_size();
|
bootstage_relocate(gd->new_bootstage);
|
||||||
|
|
||||||
debug("Copying bootstage from %p to %p, size %x\n",
|
|
||||||
gd->bootstage, gd->new_bootstage, size);
|
|
||||||
memcpy(gd->new_bootstage, gd->bootstage, size);
|
|
||||||
gd->bootstage = gd->new_bootstage;
|
|
||||||
bootstage_relocate();
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -54,12 +54,16 @@ struct bootstage_hdr {
|
|||||||
u32 next_id; /* Next ID to use for bootstage */
|
u32 next_id; /* Next ID to use for bootstage */
|
||||||
};
|
};
|
||||||
|
|
||||||
int bootstage_relocate(void)
|
int bootstage_relocate(void *to)
|
||||||
{
|
{
|
||||||
struct bootstage_data *data = gd->bootstage;
|
struct bootstage_data *data;
|
||||||
int i;
|
int i;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
|
||||||
|
debug("Copying bootstage from %p to %p\n", gd->bootstage, to);
|
||||||
|
memcpy(to, gd->bootstage, sizeof(struct bootstage_data));
|
||||||
|
data = gd->bootstage = to;
|
||||||
|
|
||||||
/* Figure out where to relocate the strings to */
|
/* Figure out where to relocate the strings to */
|
||||||
ptr = (char *)(data + 1);
|
ptr = (char *)(data + 1);
|
||||||
|
|
||||||
|
@@ -258,7 +258,7 @@ void show_boot_progress(int val);
|
|||||||
* relocation, since memory can be overwritten later.
|
* relocation, since memory can be overwritten later.
|
||||||
* Return: Always returns 0, to indicate success
|
* Return: Always returns 0, to indicate success
|
||||||
*/
|
*/
|
||||||
int bootstage_relocate(void);
|
int bootstage_relocate(void *to);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new bootstage record
|
* Add a new bootstage record
|
||||||
@@ -395,7 +395,7 @@ static inline ulong bootstage_add_record(enum bootstage_id id,
|
|||||||
* and won't even do that unless CONFIG_SHOW_BOOT_PROGRESS is defined
|
* and won't even do that unless CONFIG_SHOW_BOOT_PROGRESS is defined
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline int bootstage_relocate(void)
|
static inline int bootstage_relocate(void *to)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user