diff --git a/arch/arm/src/armv7-a/arm_addrenv_perms.c b/arch/arm/src/armv7-a/arm_addrenv_perms.c index c396f9f1e2..f9e1092e11 100644 --- a/arch/arm/src/armv7-a/arm_addrenv_perms.c +++ b/arch/arm/src/armv7-a/arm_addrenv_perms.c @@ -25,51 +25,40 @@ #include #include +#include + +#include /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: up_addrenv_text_enable_write + * Name: up_addrenv_mprot * * Description: - * Temporarily enable write access to the .text section. This must be - * called prior to loading the process code into memory. + * Modify access rights to an address range. * * Input Parameters: * addrenv - The address environment to be modified. + * addr - Base address of the region. + * len - Size of the region. + * prot - Access right flags. * * Returned Value: * Zero (OK) on success; a negated errno value on failure. * ****************************************************************************/ -int up_addrenv_text_enable_write(group_addrenv_t *addrenv) +int up_addrenv_mprot(group_addrenv_t *addrenv, uintptr_t addr, size_t len, + int prot) { /* Nothing needs to be done */ - return OK; -} - -/**************************************************************************** - * Name: up_addrenv_text_disable_write - * - * Description: - * Disable write access to the .text section. This must be called after the - * process code is loaded into memory. - * - * Input Parameters: - * addrenv - The address environment to be modified. - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -int up_addrenv_text_disable_write(group_addrenv_t *addrenv) -{ - /* Nothing needs to be done */ + UNUSED(addrenv); + UNUSED(addr); + UNUSED(len); + UNUSED(prot); return OK; } diff --git a/arch/risc-v/src/common/riscv_addrenv_perms.c b/arch/risc-v/src/common/riscv_addrenv_perms.c index a234b647a6..62acc2f3f6 100644 --- a/arch/risc-v/src/common/riscv_addrenv_perms.c +++ b/arch/risc-v/src/common/riscv_addrenv_perms.c @@ -33,15 +33,22 @@ #include +#include + #include "pgalloc.h" #include "riscv_mmu.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CLR_MASK (PTE_R | PTE_W | PTE_X) + /**************************************************************************** * Private Functions ****************************************************************************/ -static int modify_region(uintptr_t vstart, uintptr_t vend, uintptr_t setmask, - uintptr_t clrmask) +static int modify_region(uintptr_t vstart, uintptr_t vend, uintptr_t setmask) { uintptr_t l1vaddr; uintptr_t lnvaddr; @@ -78,7 +85,7 @@ static int modify_region(uintptr_t vstart, uintptr_t vend, uintptr_t setmask, /* Get entry and modify the flags */ entry = mmu_ln_getentry(ptlevel, lnvaddr, vaddr); - entry &= ~clrmask; + entry &= ~CLR_MASK; entry |= setmask; /* Restore the entry */ @@ -99,53 +106,49 @@ static int modify_region(uintptr_t vstart, uintptr_t vend, uintptr_t setmask, ****************************************************************************/ /**************************************************************************** - * Name: up_addrenv_text_enable_write + * Name: up_addrenv_mprot * * Description: - * Temporarily enable write access to the .text section. This must be - * called prior to loading the process code into memory. + * Modify access rights to an address range. * * Input Parameters: * addrenv - The address environment to be modified. + * addr - Base address of the region. + * len - Size of the region. + * prot - Access right flags. * * Returned Value: * Zero (OK) on success; a negated errno value on failure. * ****************************************************************************/ -int up_addrenv_text_enable_write(group_addrenv_t *addrenv) +int up_addrenv_mprot(group_addrenv_t *addrenv, uintptr_t addr, size_t len, + int prot) { - /* Sanity checks */ + uintptr_t setmask; + uintptr_t vend; - DEBUGASSERT(addrenv); - DEBUGASSERT(MM_ISALIGNED(addrenv->textvbase)); - DEBUGASSERT(MM_ISALIGNED(addrenv->datavbase)); + /* addrenv not needed by this implementation */ - return modify_region(addrenv->textvbase, addrenv->datavbase, PTE_W, 0); -} - -/**************************************************************************** - * Name: up_addrenv_text_disable_write - * - * Description: - * Disable write access to the .text section. This must be called after the - * process code is loaded into memory. - * - * Input Parameters: - * addrenv - The address environment to be modified. - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -int up_addrenv_text_disable_write(group_addrenv_t *addrenv) -{ - /* Sanity checks */ - - DEBUGASSERT(addrenv); - DEBUGASSERT(MM_ISALIGNED(addrenv->textvbase)); - DEBUGASSERT(MM_ISALIGNED(addrenv->datavbase)); - - return modify_region(addrenv->textvbase, addrenv->datavbase, 0, PTE_W); + UNUSED(addrenv); + + setmask = 0; + vend = addr + MM_PGALIGNUP(len); + + if (prot & PROT_READ) + { + setmask |= PTE_R; + } + + if (prot & PROT_WRITE) + { + setmask |= PTE_W; + } + + if (prot & PROT_EXEC) + { + setmask |= PTE_X; + } + + return modify_region(addr, vend, setmask); } diff --git a/binfmt/libelf/libelf_addrenv.c b/binfmt/libelf/libelf_addrenv.c index 4504a98ecc..3e44d2eab0 100644 --- a/binfmt/libelf/libelf_addrenv.c +++ b/binfmt/libelf/libelf_addrenv.c @@ -30,12 +30,17 @@ #include #include +#include + #include "libelf.h" /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +#define ELF_TEXT_WRE (PROT_READ | PROT_WRITE | PROT_EXEC) +#define ELF_TEXT_WRD (PROT_READ | PROT_EXEC) + /**************************************************************************** * Private Constant Data ****************************************************************************/ @@ -175,7 +180,8 @@ int elf_addrenv_select(FAR struct elf_loadinfo_s *loadinfo) /* Allow write access to .text */ - ret = up_addrenv_text_enable_write(&loadinfo->addrenv); + ret = up_addrenv_mprot(&loadinfo->addrenv, loadinfo->textalloc, + loadinfo->textsize, ELF_TEXT_WRE); if (ret < 0) { berr("ERROR: up_addrenv_text_enable_write failed: %d\n", ret); @@ -207,7 +213,8 @@ int elf_addrenv_restore(FAR struct elf_loadinfo_s *loadinfo) /* Remove write access to .text */ - ret = up_addrenv_text_disable_write(&loadinfo->addrenv); + ret = up_addrenv_mprot(&loadinfo->addrenv, loadinfo->textalloc, + loadinfo->textsize, ELF_TEXT_WRD); if (ret < 0) { berr("ERROR: up_addrenv_text_disable_write failed: %d\n", ret); diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 116c3d192b..8bc8442ab1 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -1186,14 +1186,16 @@ int up_addrenv_detach(FAR struct task_group_s *group, FAR struct tcb_s *tcb); #endif /**************************************************************************** - * Name: up_addrenv_text_enable_write + * Name: up_addrenv_mprot * * Description: - * Temporarily enable write access to the .text section. This must be - * called prior to loading the process code into memory. + * Modify access rights to an address range. * * Input Parameters: * addrenv - The address environment to be modified. + * addr - Base address of the region. + * len - Size of the region. + * prot - Access right flags. * * Returned Value: * Zero (OK) on success; a negated errno value on failure. @@ -1201,26 +1203,8 @@ int up_addrenv_detach(FAR struct task_group_s *group, FAR struct tcb_s *tcb); ****************************************************************************/ #ifdef CONFIG_ARCH_ADDRENV -int up_addrenv_text_enable_write(FAR group_addrenv_t *addrenv); -#endif - -/**************************************************************************** - * Name: up_addrenv_text_disable_write - * - * Description: - * Disable write access to the .text section. This must be called after the - * process code is loaded into memory. - * - * Input Parameters: - * addrenv - The address environment to be modified. - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -#ifdef CONFIG_ARCH_ADDRENV -int up_addrenv_text_disable_write(FAR group_addrenv_t *addrenv); +int up_addrenv_mprot(group_addrenv_t *addrenv, uintptr_t addr, size_t len, + int prot); #endif /****************************************************************************