arch/addrenv: Change text write enable/disable to generic mprot
Implement a generic access rights modification procedure instead of the procedures that only do one thing (enable/disable write) to one section (text).
This commit is contained in:
parent
072c28fe8e
commit
47e85b68fe
@ -25,51 +25,40 @@
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/compiler.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
/****************************************************************************
|
||||
* 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;
|
||||
}
|
||||
|
@ -33,15 +33,22 @@
|
||||
|
||||
#include <arch/barriers.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
@ -30,12 +30,17 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#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);
|
||||
|
@ -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
|
||||
|
||||
/****************************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user