From 4449b001e2250721c228b2bc8a9a201268ab68f5 Mon Sep 17 00:00:00 2001 From: Michalis Pappas Date: Wed, 17 Dec 2025 14:36:18 +0100 Subject: [PATCH 1/3] Updates for libukpaging Update implementation to use the libukpaging API. Signed-off-by: Michalis Pappas --- elf_load.c | 58 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/elf_load.c b/elf_load.c index ffdc24c..f78e8e4 100644 --- a/elf_load.c +++ b/elf_load.c @@ -63,6 +63,7 @@ #include #endif /* CONFIG_LIBUKVMEM */ #include +#include #include "libelf_helper.h" #include "elf_prog.h" @@ -229,7 +230,7 @@ static int elf_load_parse(struct elf_prog *elf_prog, Elf *elf) elf_prog->phdr.num = ehdr.e_phnum; elf_prog->phdr.entsize = ehdr.e_phentsize; - elf_prog->valen = PAGE_ALIGN_UP(elf_prog->upperl); + elf_prog->valen = UK_PAGING_PAGE_ALIGN_UP(elf_prog->upperl); return 0; err_out: @@ -273,7 +274,7 @@ static int elf_load_imgcpy(struct elf_prog *elf_prog, Elf *elf, GElf_Phdr phdr; int ret; - UK_ASSERT(elf_prog->align && PAGE_ALIGNED(elf_prog->align)); + UK_ASSERT(elf_prog->align && UK_PAGING_PAGE_ALIGNED(elf_prog->align)); if (unlikely(gelf_getehdr(elf, &ehdr) == NULL)) { elferr_err("%s: Failed to get executable header", @@ -331,7 +332,7 @@ static int elf_load_imgcpy(struct elf_prog *elf_prog, Elf *elf, /* Compute the area that needs to be zeroed */ vastart = vaend; vaend = vastart + (phdr.p_memsz - phdr.p_filesz); - vaend = PAGE_ALIGN_UP(vaend); + vaend = UK_PAGING_PAGE_ALIGN_UP(vaend); uk_pr_debug("%s: Zeroing 0x%"PRIx64" - 0x%"PRIx64"\n", elf_prog->name, (uint64_t) (vastart), @@ -367,28 +368,29 @@ static int elf_load_mmap_filesz_memsz_diff(struct elf_prog *elf_prog, /* From the last byte contained in filesz to the last * byte contained in memsz, we can either have: * 1. a page alignment adjustment, where the end - * address is just PAGE_ALIGN_UP(paddr + filesz), which - * means that our initial call to mmap already read in + * address is just UK_PAGING_PAGE_ALIGN_UP(paddr + filesz), + * which means that our initial call to mmap already read in * a page for us whose remaining bytes we memset without * generating a page fault, because - * vaend - vastart < PAGE_SIZE + * vaend - vastart < UK_PAGING_PAGE_SIZE * ... */ - memset((void *)vastart, 0, PAGE_ALIGN_UP(vastart) - vastart); + memset((void *)vastart, 0, + UK_PAGING_PAGE_ALIGN_UP(vastart) - vastart); } - if (vaend == PAGE_ALIGN_UP(vastart)) + if (vaend == UK_PAGING_PAGE_ALIGN_UP(vastart)) return 0; /* * ... - * 2. vaend - vastart >= PAGE_SIZE, which can happen if + * 2. vaend - vastart >= UK_PAGING_PAGE_SIZE, which can happen if * this segment contains a NOBITS section, such as .bss. * If that is the case, then simply anonymously map this * remaining area so that we don't waste time memsetting * it (.bss is quite large). */ - vastart = PAGE_ALIGN_UP(vastart); + vastart = UK_PAGING_PAGE_ALIGN_UP(vastart); vastart = (uintptr_t)mmap((void *)vastart, vaend - vastart, get_phdr_mmap_prot(phdr), MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, @@ -470,7 +472,8 @@ static int do_elf_load_fdphdr_0(struct elf_prog *elf_prog, /* mmap anonymously what we are left if memsz > filesz */ vastart += phdr->p_filesz; - vaend = PAGE_ALIGN_UP(vastart + (phdr->p_memsz - phdr->p_filesz)); + vaend = UK_PAGING_PAGE_ALIGN_UP(vastart + (phdr->p_memsz - + phdr->p_filesz)); if (vaend > vastart) { rc = elf_load_mmap_filesz_memsz_diff(elf_prog, phdr, vastart, vaend); @@ -504,10 +507,11 @@ static int do_elf_load_fdphdr_not0(struct elf_prog *elf_prog, * Therefore, taking care of the address misalignment will also take * care of the file misalignment. */ - delta_p_offset = phdr->p_vaddr - PAGE_ALIGN_DOWN(phdr->p_vaddr); + delta_p_offset = phdr->p_vaddr - + UK_PAGING_PAGE_ALIGN_DOWN(phdr->p_vaddr); - addr = (void *)PAGE_ALIGN_DOWN((phdr->p_vaddr + - (uintptr_t)elf_prog->vabase)); + addr = (void *)UK_PAGING_PAGE_ALIGN_DOWN((phdr->p_vaddr + + (uintptr_t)elf_prog->vabase)); uk_pr_debug("%s: Memory mapping 0x%"PRIx64" - 0x%"PRIx64" to 0x%"PRIx64" - 0x%"PRIx64"\n", elf_prog->name, @@ -531,11 +535,11 @@ static int do_elf_load_fdphdr_not0(struct elf_prog *elf_prog, } vastart += phdr->p_filesz + delta_p_offset; - vaend = PAGE_ALIGN_UP(vastart + + vaend = UK_PAGING_PAGE_ALIGN_UP(vastart + (phdr->p_memsz - phdr->p_filesz)); } else { vastart = (uintptr_t)addr; - vaend = PAGE_ALIGN_UP(vastart + phdr->p_memsz + + vaend = UK_PAGING_PAGE_ALIGN_UP(vastart + phdr->p_memsz + delta_p_offset); } @@ -618,7 +622,7 @@ static int elf_load_fdphdr(struct elf_prog *elf_prog, GElf_Phdr *phdr, int fd) /* Compute the area that needs to be zeroed */ vastart = vaend; vaend = vastart + (phdr->p_memsz - phdr->p_filesz); - vaend = PAGE_ALIGN_UP(vaend); + vaend = UK_PAGING_PAGE_ALIGN_UP(vaend); uk_pr_debug("%s: Zeroing 0x%"PRIx64" - 0x%"PRIx64"\n", elf_prog->name, (uint64_t)(vastart), @@ -636,7 +640,7 @@ static int elf_load_fd(struct elf_prog *elf_prog, Elf *elf, int fd) GElf_Phdr phdr; int ret = -1; - UK_ASSERT(elf_prog->align && PAGE_ALIGNED(elf_prog->align)); + UK_ASSERT(elf_prog->align && UK_PAGING_PAGE_ALIGNED(elf_prog->align)); if (unlikely(gelf_getehdr(elf, &ehdr) == NULL)) { elferr_err("%s: Failed to get executable header", @@ -783,8 +787,8 @@ static int elf_load_ptprotect(struct elf_prog *elf_prog, Elf *elf) vastart = phdr.p_vaddr + (uintptr_t)elf_prog->vabase; vaend = vastart + phdr.p_memsz; - vastart = PAGE_ALIGN_DOWN(vastart); - vaend = PAGE_ALIGN_UP(vaend); + vastart = UK_PAGING_PAGE_ALIGN_DOWN(vastart); + vaend = UK_PAGING_PAGE_ALIGN_UP(vaend); valen = vaend - vastart; uk_pr_debug("%s: Protecting 0x%"PRIx64" - 0x%"PRIx64": %c%c%c\n", elf_prog->name, @@ -795,11 +799,11 @@ static int elf_load_ptprotect(struct elf_prog *elf_prog, Elf *elf) phdr.p_flags & PF_X ? 'X' : '-'); ret = uk_vma_set_attr(vas, vastart, valen, ((phdr.p_flags & PF_R) ? - PAGE_ATTR_PROT_READ : 0x0) | + UK_PAGING_PAGE_ATTR_PROT_READ : 0x0) | ((phdr.p_flags & PF_W) ? - PAGE_ATTR_PROT_WRITE : 0x0) | + UK_PAGING_PAGE_ATTR_PROT_WRITE : 0x0) | ((phdr.p_flags & PF_X) ? - PAGE_ATTR_PROT_EXEC : 0x0), + UK_PAGING_PAGE_ATTR_PROT_EXEC : 0x0), 0); if (ret < 0) uk_pr_err("%s: Failed to set protection bits: %d. Program execution may fail or might be unsafe.\n", @@ -825,13 +829,15 @@ static void elf_unload_ptunprotect(struct elf_prog *elf_prog) vastart = (uintptr_t) elf_prog->vabase; vaend = vastart + (uintptr_t) elf_prog->valen; - vastart = PAGE_ALIGN_DOWN(vastart); - vaend = PAGE_ALIGN_UP(vaend); + vastart = UK_PAGING_PAGE_ALIGN_DOWN(vastart); + vaend = UK_PAGING_PAGE_ALIGN_UP(vaend); valen = vaend - vastart; uk_pr_debug("%s: Restore RW- protection: 0x%"PRIx64" - 0x%"PRIx64"\n", elf_prog->name, (uint64_t) vastart, (uint64_t) vaend); ret = uk_vma_set_attr(vas, vastart, valen, - (PAGE_ATTR_PROT_READ | PAGE_ATTR_PROT_WRITE), 0); + (UK_PAGING_PAGE_ATTR_PROT_READ | + UK_PAGING_PAGE_ATTR_PROT_WRITE), + 0); if (unlikely(ret < 0)) uk_pr_err("%s: Failed to restore protection bits: %d.\n", elf_prog->name, ret); From 442fadd8400aeb3659a0d1c1cca1c0d7854620a9 Mon Sep 17 00:00:00 2001 From: Sergiu Moga Date: Thu, 5 Feb 2026 16:38:19 +0200 Subject: [PATCH 2/3] Remove `bootstrap.h`, obsoleted in favor of `libukpm` The introduction of `libukpm` into the core obsoleted the `bootstrap.h` header and its related implementations, therefore, remove its inclusion from here as well. Signed-off-by: Sergiu Moga --- elf_ctx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/elf_ctx.c b/elf_ctx.c index 39b9021..fe84f21 100644 --- a/elf_ctx.c +++ b/elf_ctx.c @@ -48,7 +48,6 @@ #include #include -#include #include #include #include From eb538b700504b8a194406f9848ecb43031ec90bc Mon Sep 17 00:00:00 2001 From: Sergiu Moga Date: Thu, 5 Feb 2026 16:40:01 +0200 Subject: [PATCH 3/3] Fix return value and invalid free upon nonexisting executable If the executable is not found in the environment, the `ret` variable is not updated to the correct error value and `realpath` has an invalid value which will cause an invalid page fault upon `free` attempt. Apply this check to `progname_conv` while at it as well, to be sure. Signed-off-by: Sergiu Moga --- main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/main.c b/main.c index 7876863..93f4cad 100644 --- a/main.c +++ b/main.c @@ -267,9 +267,10 @@ int main(int argc, const char *argv[]) if (PTR2ERR(realpath) == -EINVAL) { realpath = NULL; } else if (PTRISERR(realpath) && PTR2ERR(realpath) != -EINVAL) { - uk_pr_err("%s: Failed to find executable in environment ($PATH): %s (%d)", + uk_pr_err("%s: Failed to find executable in environment ($PATH): %s (%d)\n", progname, strerror(-PTR2ERR(realpath)), PTR2ERR(realpath)); + ret = PTR2ERR(realpath); goto out; } } @@ -425,10 +426,10 @@ int main(int argc, const char *argv[]) out: #if CONFIG_APPELFLOADER_VFSEXEC #if CONFIG_APPELFLOADER_VFSEXEC_ENVPATH - if (realpath) + if (realpath && !PTRISERR(realpath)) free(realpath); #endif /* CONFIG_APPELFLOADER_VFSEXEC_ENVPATH */ - if (progname_conv) + if (progname_conv && !PTRISERR(progname_conv)) free(progname_conv); #endif /* CONFIG_APPELFLOADER_VFSEXEC */ return ret;