Skip to content

Commit 6dded12

Browse files
committed
elf_loader: resolve outstanding validation fixme
Signed-off-by: Carl van Schaik <quic_cvanscha@quicinc.com>
1 parent c667ce8 commit 6dded12

File tree

3 files changed

+50
-19
lines changed

3 files changed

+50
-19
lines changed

hyp/interfaces/elf/include/elf_loader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ elf_get_phdr(void *elf_file, count_t index);
2020

2121
// Load the ELF file to its physical address as per its program headers
2222
error_t
23-
elf_load_phys(void *elf_file, paddr_t phys_offset);
23+
elf_load_phys(void *elf_file, size_t elf_max_size, paddr_t phys_base);

hyp/misc/elf/src/elf_loader.c

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,9 @@ elf_get_phdr(void *elf_file, count_t index)
124124
}
125125

126126
error_t
127-
elf_load_phys(void *elf_file, paddr_t phys_offset)
127+
elf_load_phys(void *elf_file, size_t elf_max_size, paddr_t phys_base)
128128
{
129+
error_t ret;
129130
index_t i;
130131
uintptr_t elf_base = (uintptr_t)elf_file;
131132
Elf_Ehdr *ehdr = (Elf_Ehdr *)(uintptr_t)elf_file;
@@ -143,11 +144,31 @@ elf_load_phys(void *elf_file, paddr_t phys_offset)
143144
continue;
144145
}
145146

146-
// FIXME: validate addresses target useable HYP memory
147+
if (cur_phdr->p_filesz > cur_phdr->p_memsz) {
148+
ret = ERROR_ARGUMENT_SIZE;
149+
goto out;
150+
}
151+
152+
if (util_add_overflows(cur_phdr->p_paddr, cur_phdr->p_memsz) ||
153+
util_add_overflows(phys_base,
154+
cur_phdr->p_paddr + cur_phdr->p_memsz) ||
155+
((cur_phdr->p_offset + cur_phdr->p_filesz) >
156+
elf_max_size)) {
157+
ret = ERROR_ARGUMENT_SIZE;
158+
goto out;
159+
}
160+
161+
if (util_add_overflows(cur_phdr->p_offset, cur_phdr->p_memsz) ||
162+
util_add_overflows(elf_base, cur_phdr->p_offset +
163+
cur_phdr->p_memsz)) {
164+
ret = ERROR_ARGUMENT_SIZE;
165+
goto out;
166+
}
167+
147168
uintptr_t seg_base = elf_base + cur_phdr->p_offset;
148-
paddr_t seg_dest = cur_phdr->p_paddr + phys_offset;
169+
paddr_t seg_dest = phys_base + cur_phdr->p_paddr;
149170

150-
error_t ret;
171+
error_t err;
151172

152173
paddr_t map_base = util_balign_down(
153174
seg_dest, (paddr_t)PGTABLE_HYP_PAGE_SIZE);
@@ -157,24 +178,25 @@ elf_load_phys(void *elf_file, paddr_t phys_offset)
157178
map_base;
158179

159180
// FIXME: should we use phys_map and phys_access eventually?
160-
ret = hyp_aspace_map_direct(map_base, map_size,
181+
err = hyp_aspace_map_direct(map_base, map_size,
161182
PGTABLE_ACCESS_RW,
162183
PGTABLE_HYP_MEMTYPE_WRITETHROUGH,
163184
VMSA_SHAREABILITY_INNER_SHAREABLE);
164-
assert(ret == OK);
185+
assert(err == OK);
165186

166187
// copy elf segment data
167188
memcpy((char *)seg_dest, (char *)seg_base, cur_phdr->p_filesz);
168-
if (cur_phdr->p_memsz > cur_phdr->p_filesz) {
169-
// zero bss
170-
memset((char *)(seg_dest + cur_phdr->p_filesz), 0,
171-
cur_phdr->p_memsz - cur_phdr->p_filesz);
172-
}
189+
// zero bss
190+
memset((char *)(seg_dest + cur_phdr->p_filesz), 0,
191+
cur_phdr->p_memsz - cur_phdr->p_filesz);
173192

174193
LOG(DEBUG, INFO, "Elf copied from {:#x} to {:#x} - size {:#x}",
175194
seg_base, seg_dest, cur_phdr->p_filesz);
176-
ret = hyp_aspace_unmap_direct(map_base, map_size);
177-
assert(ret == OK);
195+
err = hyp_aspace_unmap_direct(map_base, map_size);
196+
assert(err == OK);
178197
}
179-
return OK;
198+
199+
ret = OK;
200+
out:
201+
return ret;
180202
}

hyp/vm/rootvm_package/src/package.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,9 @@ create_memextent(partition_t *root_partition, cspace_t *root_cspace,
8080
}
8181

8282
static paddr_t
83-
rootvm_package_load_elf(void *elf, addrspace_t *addrspace, vmaddr_t ipa_base,
84-
paddr_t phys_offset, memextent_t *me_rm)
83+
rootvm_package_load_elf(void *elf, size_t elf_max_size, addrspace_t *addrspace,
84+
vmaddr_t ipa_base, paddr_t phys_offset,
85+
memextent_t *me_rm)
8586
{
8687
error_t err;
8788
count_t i;
@@ -147,7 +148,7 @@ rootvm_package_load_elf(void *elf, addrspace_t *addrspace, vmaddr_t ipa_base,
147148
panic("ELF segment out of range");
148149
}
149150

150-
err = elf_load_phys(elf, phys_offset);
151+
err = elf_load_phys(elf, elf_max_size, phys_offset);
151152
if (err != OK) {
152153
panic("Error loading ELF");
153154
}
@@ -239,6 +240,13 @@ rootvm_package_handle_rootvm_init(partition_t *root_partition,
239240
void *elf =
240241
(void *)(map_base + pkg_hdr->list[i].offset);
241242

243+
if (pkg_hdr->list[i].offset > map_size) {
244+
panic("ELF out of valid region");
245+
}
246+
247+
size_t elf_max_size =
248+
map_size - pkg_hdr->list[i].offset;
249+
242250
if (!elf_valid(elf)) {
243251
panic("Invalid package ELF");
244252
}
@@ -254,7 +262,8 @@ rootvm_package_handle_rootvm_init(partition_t *root_partition,
254262
app_ipa = ipa + offset;
255263
}
256264

257-
load_next = rootvm_package_load_elf(elf, addrspace, ipa,
265+
load_next = rootvm_package_load_elf(elf, elf_max_size,
266+
addrspace, ipa,
258267
load_next, me);
259268
break;
260269
case ROOTVM_PACKAGE_IMAGE_TYPE_UNKNOWN:

0 commit comments

Comments
 (0)