Commit 9cc2323feebdde500f50f7abb855045dbde765cb
Committed by
Tom Rini
1 parent
e3b4fc9598
Exists in
smarc_8mq_lf_v2020.04
and in
11 other branches
lmb: handle more than one DRAM BANK
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 <xypron.glpk@gmx.de> Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com> Tested-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Reviewed-by: Simon Glass <sjg@chromium.org>
Showing 5 changed files with 41 additions and 13 deletions Side-by-side Diff
common/bootm.c
... | ... | @@ -59,8 +59,8 @@ |
59 | 59 | mem_start = env_get_bootm_low(); |
60 | 60 | mem_size = env_get_bootm_size(); |
61 | 61 | |
62 | - lmb_init_and_reserve(&images->lmb, (phys_addr_t)mem_start, mem_size, | |
63 | - NULL); | |
62 | + lmb_init_and_reserve_range(&images->lmb, (phys_addr_t)mem_start, | |
63 | + mem_size, NULL); | |
64 | 64 | } |
65 | 65 | #else |
66 | 66 | #define lmb_reserve(lmb, base, size) |
fs/fs.c
... | ... | @@ -454,8 +454,7 @@ |
454 | 454 | if (len && len < read_len) |
455 | 455 | read_len = len; |
456 | 456 | |
457 | - lmb_init_and_reserve(&lmb, gd->bd->bi_dram[0].start, | |
458 | - gd->bd->bi_dram[0].size, (void *)gd->fdt_blob); | |
457 | + lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob); | |
459 | 458 | lmb_dump_all(&lmb); |
460 | 459 | |
461 | 460 | if (lmb_alloc_addr(&lmb, addr, read_len) == addr) |
include/lmb.h
... | ... | @@ -4,6 +4,8 @@ |
4 | 4 | #ifdef __KERNEL__ |
5 | 5 | |
6 | 6 | #include <asm/types.h> |
7 | +#include <asm/u-boot.h> | |
8 | + | |
7 | 9 | /* |
8 | 10 | * Logical memory blocks. |
9 | 11 | * |
... | ... | @@ -29,8 +31,9 @@ |
29 | 31 | }; |
30 | 32 | |
31 | 33 | extern void lmb_init(struct lmb *lmb); |
32 | -extern void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base, | |
33 | - phys_size_t size, void *fdt_blob); | |
34 | +extern void lmb_init_and_reserve(struct lmb *lmb, bd_t *bd, void *fdt_blob); | |
35 | +extern void lmb_init_and_reserve_range(struct lmb *lmb, phys_addr_t base, | |
36 | + phys_size_t size, void *fdt_blob); | |
34 | 37 | extern long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size); |
35 | 38 | extern long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size); |
36 | 39 | extern phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align); |
lib/lmb.c
... | ... | @@ -98,17 +98,44 @@ |
98 | 98 | lmb->reserved.size = 0; |
99 | 99 | } |
100 | 100 | |
101 | -/* Initialize the struct, add memory and call arch/board reserve functions */ | |
102 | -void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size, | |
103 | - void *fdt_blob) | |
101 | +static void lmb_reserve_common(struct lmb *lmb, void *fdt_blob) | |
104 | 102 | { |
105 | - lmb_init(lmb); | |
106 | - lmb_add(lmb, base, size); | |
107 | 103 | arch_lmb_reserve(lmb); |
108 | 104 | board_lmb_reserve(lmb); |
109 | 105 | |
110 | 106 | if (IMAGE_ENABLE_OF_LIBFDT && fdt_blob) |
111 | 107 | boot_fdt_add_mem_rsv_regions(lmb, fdt_blob); |
108 | +} | |
109 | + | |
110 | +/* Initialize the struct, add memory and call arch/board reserve functions */ | |
111 | +void lmb_init_and_reserve(struct lmb *lmb, bd_t *bd, void *fdt_blob) | |
112 | +{ | |
113 | +#ifdef CONFIG_NR_DRAM_BANKS | |
114 | + int i; | |
115 | +#endif | |
116 | + | |
117 | + lmb_init(lmb); | |
118 | +#ifdef CONFIG_NR_DRAM_BANKS | |
119 | + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { | |
120 | + if (bd->bi_dram[i].size) { | |
121 | + lmb_add(lmb, bd->bi_dram[i].start, | |
122 | + bd->bi_dram[i].size); | |
123 | + } | |
124 | + } | |
125 | +#else | |
126 | + if (bd->bi_memsize) | |
127 | + lmb_add(lmb, bd->bi_memstart, bd->bi_memsize); | |
128 | +#endif | |
129 | + lmb_reserve_common(lmb, fdt_blob); | |
130 | +} | |
131 | + | |
132 | +/* Initialize the struct, add memory and call arch/board reserve functions */ | |
133 | +void lmb_init_and_reserve_range(struct lmb *lmb, phys_addr_t base, | |
134 | + phys_size_t size, void *fdt_blob) | |
135 | +{ | |
136 | + lmb_init(lmb); | |
137 | + lmb_add(lmb, base, size); | |
138 | + lmb_reserve_common(lmb, fdt_blob); | |
112 | 139 | } |
113 | 140 | |
114 | 141 | /* This routine called with relocation disabled. */ |
net/tftp.c
... | ... | @@ -606,8 +606,7 @@ |
606 | 606 | struct lmb lmb; |
607 | 607 | phys_size_t max_size; |
608 | 608 | |
609 | - lmb_init_and_reserve(&lmb, gd->bd->bi_dram[0].start, | |
610 | - gd->bd->bi_dram[0].size, (void *)gd->fdt_blob); | |
609 | + lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob); | |
611 | 610 | |
612 | 611 | max_size = lmb_get_free_size(&lmb, load_addr); |
613 | 612 | if (!max_size) |