Skip to content

Commit

Permalink
lmb: handle more than one DRAM BANK
Browse files Browse the repository at this point in the history
This fixes the automatic lmb initialization and reservation for boards
with more than one DRAM bank.

This fixes the CVE-2018-18439 and -18440 fixes that only allowed to load
files into the firs DRAM bank from fs and via tftp.

Found-by: Heinrich Schuchardt <[email protected]>
Signed-off-by: Simon Goldschmidt <[email protected]>
Tested-by: Heinrich Schuchardt <[email protected]>
Reviewed-by: Simon Glass <[email protected]>
  • Loading branch information
goldsimon authored and trini committed Feb 2, 2019
1 parent e3b4fc9 commit 9cc2323
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 13 deletions.
4 changes: 2 additions & 2 deletions common/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ static void boot_start_lmb(bootm_headers_t *images)
mem_start = env_get_bootm_low();
mem_size = env_get_bootm_size();

lmb_init_and_reserve(&images->lmb, (phys_addr_t)mem_start, mem_size,
NULL);
lmb_init_and_reserve_range(&images->lmb, (phys_addr_t)mem_start,
mem_size, NULL);
}
#else
#define lmb_reserve(lmb, base, size)
Expand Down
3 changes: 1 addition & 2 deletions fs/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,8 +454,7 @@ static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset,
if (len && len < read_len)
read_len = len;

lmb_init_and_reserve(&lmb, gd->bd->bi_dram[0].start,
gd->bd->bi_dram[0].size, (void *)gd->fdt_blob);
lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
lmb_dump_all(&lmb);

if (lmb_alloc_addr(&lmb, addr, read_len) == addr)
Expand Down
7 changes: 5 additions & 2 deletions include/lmb.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#ifdef __KERNEL__

#include <asm/types.h>
#include <asm/u-boot.h>

/*
* Logical memory blocks.
*
Expand All @@ -29,8 +31,9 @@ struct lmb {
};

extern void lmb_init(struct lmb *lmb);
extern void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base,
phys_size_t size, void *fdt_blob);
extern void lmb_init_and_reserve(struct lmb *lmb, bd_t *bd, void *fdt_blob);
extern void lmb_init_and_reserve_range(struct lmb *lmb, phys_addr_t base,
phys_size_t size, void *fdt_blob);
extern long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size);
extern long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size);
extern phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align);
Expand Down
37 changes: 32 additions & 5 deletions lib/lmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,46 @@ void lmb_init(struct lmb *lmb)
lmb->reserved.size = 0;
}

/* Initialize the struct, add memory and call arch/board reserve functions */
void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size,
void *fdt_blob)
static void lmb_reserve_common(struct lmb *lmb, void *fdt_blob)
{
lmb_init(lmb);
lmb_add(lmb, base, size);
arch_lmb_reserve(lmb);
board_lmb_reserve(lmb);

if (IMAGE_ENABLE_OF_LIBFDT && fdt_blob)
boot_fdt_add_mem_rsv_regions(lmb, fdt_blob);
}

/* Initialize the struct, add memory and call arch/board reserve functions */
void lmb_init_and_reserve(struct lmb *lmb, bd_t *bd, void *fdt_blob)
{
#ifdef CONFIG_NR_DRAM_BANKS
int i;
#endif

lmb_init(lmb);
#ifdef CONFIG_NR_DRAM_BANKS
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
if (bd->bi_dram[i].size) {
lmb_add(lmb, bd->bi_dram[i].start,
bd->bi_dram[i].size);
}
}
#else
if (bd->bi_memsize)
lmb_add(lmb, bd->bi_memstart, bd->bi_memsize);
#endif
lmb_reserve_common(lmb, fdt_blob);
}

/* Initialize the struct, add memory and call arch/board reserve functions */
void lmb_init_and_reserve_range(struct lmb *lmb, phys_addr_t base,
phys_size_t size, void *fdt_blob)
{
lmb_init(lmb);
lmb_add(lmb, base, size);
lmb_reserve_common(lmb, fdt_blob);
}

/* This routine called with relocation disabled. */
static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t size)
{
Expand Down
3 changes: 1 addition & 2 deletions net/tftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,8 +606,7 @@ static int tftp_init_load_addr(void)
struct lmb lmb;
phys_size_t max_size;

lmb_init_and_reserve(&lmb, gd->bd->bi_dram[0].start,
gd->bd->bi_dram[0].size, (void *)gd->fdt_blob);
lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);

max_size = lmb_get_free_size(&lmb, load_addr);
if (!max_size)
Expand Down

0 comments on commit 9cc2323

Please sign in to comment.