mirror of
https://github.com/apache/nuttx.git
synced 2026-06-05 15:58:59 +08:00
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:
@@ -25,51 +25,40 @@
|
|||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/compiler.h>
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_addrenv_text_enable_write
|
* Name: up_addrenv_mprot
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Temporarily enable write access to the .text section. This must be
|
* Modify access rights to an address range.
|
||||||
* called prior to loading the process code into memory.
|
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* addrenv - The address environment to be modified.
|
* addrenv - The address environment to be modified.
|
||||||
|
* addr - Base address of the region.
|
||||||
|
* len - Size of the region.
|
||||||
|
* prot - Access right flags.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Zero (OK) on success; a negated errno value on failure.
|
* 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 */
|
/* Nothing needs to be done */
|
||||||
|
|
||||||
return OK;
|
UNUSED(addrenv);
|
||||||
}
|
UNUSED(addr);
|
||||||
|
UNUSED(len);
|
||||||
/****************************************************************************
|
UNUSED(prot);
|
||||||
* 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 */
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,15 +33,22 @@
|
|||||||
|
|
||||||
#include <arch/barriers.h>
|
#include <arch/barriers.h>
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
#include "pgalloc.h"
|
#include "pgalloc.h"
|
||||||
#include "riscv_mmu.h"
|
#include "riscv_mmu.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define CLR_MASK (PTE_R | PTE_W | PTE_X)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int modify_region(uintptr_t vstart, uintptr_t vend, uintptr_t setmask,
|
static int modify_region(uintptr_t vstart, uintptr_t vend, uintptr_t setmask)
|
||||||
uintptr_t clrmask)
|
|
||||||
{
|
{
|
||||||
uintptr_t l1vaddr;
|
uintptr_t l1vaddr;
|
||||||
uintptr_t lnvaddr;
|
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 */
|
/* Get entry and modify the flags */
|
||||||
|
|
||||||
entry = mmu_ln_getentry(ptlevel, lnvaddr, vaddr);
|
entry = mmu_ln_getentry(ptlevel, lnvaddr, vaddr);
|
||||||
entry &= ~clrmask;
|
entry &= ~CLR_MASK;
|
||||||
entry |= setmask;
|
entry |= setmask;
|
||||||
|
|
||||||
/* Restore the entry */
|
/* 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:
|
* Description:
|
||||||
* Temporarily enable write access to the .text section. This must be
|
* Modify access rights to an address range.
|
||||||
* called prior to loading the process code into memory.
|
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* addrenv - The address environment to be modified.
|
* addrenv - The address environment to be modified.
|
||||||
|
* addr - Base address of the region.
|
||||||
|
* len - Size of the region.
|
||||||
|
* prot - Access right flags.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Zero (OK) on success; a negated errno value on failure.
|
* 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);
|
/* addrenv not needed by this implementation */
|
||||||
DEBUGASSERT(MM_ISALIGNED(addrenv->textvbase));
|
|
||||||
DEBUGASSERT(MM_ISALIGNED(addrenv->datavbase));
|
|
||||||
|
|
||||||
return modify_region(addrenv->textvbase, addrenv->datavbase, PTE_W, 0);
|
UNUSED(addrenv);
|
||||||
}
|
|
||||||
|
setmask = 0;
|
||||||
/****************************************************************************
|
vend = addr + MM_PGALIGNUP(len);
|
||||||
* Name: up_addrenv_text_disable_write
|
|
||||||
*
|
if (prot & PROT_READ)
|
||||||
* Description:
|
{
|
||||||
* Disable write access to the .text section. This must be called after the
|
setmask |= PTE_R;
|
||||||
* process code is loaded into memory.
|
}
|
||||||
*
|
|
||||||
* Input Parameters:
|
if (prot & PROT_WRITE)
|
||||||
* addrenv - The address environment to be modified.
|
{
|
||||||
*
|
setmask |= PTE_W;
|
||||||
* Returned Value:
|
}
|
||||||
* Zero (OK) on success; a negated errno value on failure.
|
|
||||||
*
|
if (prot & PROT_EXEC)
|
||||||
****************************************************************************/
|
{
|
||||||
|
setmask |= PTE_X;
|
||||||
int up_addrenv_text_disable_write(group_addrenv_t *addrenv)
|
}
|
||||||
{
|
|
||||||
/* Sanity checks */
|
return modify_region(addr, vend, setmask);
|
||||||
|
|
||||||
DEBUGASSERT(addrenv);
|
|
||||||
DEBUGASSERT(MM_ISALIGNED(addrenv->textvbase));
|
|
||||||
DEBUGASSERT(MM_ISALIGNED(addrenv->datavbase));
|
|
||||||
|
|
||||||
return modify_region(addrenv->textvbase, addrenv->datavbase, 0, PTE_W);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,12 +30,17 @@
|
|||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
#include <nuttx/kmalloc.h>
|
#include <nuttx/kmalloc.h>
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
#include "libelf.h"
|
#include "libelf.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define ELF_TEXT_WRE (PROT_READ | PROT_WRITE | PROT_EXEC)
|
||||||
|
#define ELF_TEXT_WRD (PROT_READ | PROT_EXEC)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Constant Data
|
* Private Constant Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -175,7 +180,8 @@ int elf_addrenv_select(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
|
|
||||||
/* Allow write access to .text */
|
/* 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)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
berr("ERROR: up_addrenv_text_enable_write failed: %d\n", ret);
|
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 */
|
/* 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)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
berr("ERROR: up_addrenv_text_disable_write failed: %d\n", ret);
|
berr("ERROR: up_addrenv_text_disable_write failed: %d\n", ret);
|
||||||
|
|||||||
+7
-23
@@ -1186,14 +1186,16 @@ int up_addrenv_detach(FAR struct task_group_s *group, FAR struct tcb_s *tcb);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_addrenv_text_enable_write
|
* Name: up_addrenv_mprot
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Temporarily enable write access to the .text section. This must be
|
* Modify access rights to an address range.
|
||||||
* called prior to loading the process code into memory.
|
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* addrenv - The address environment to be modified.
|
* addrenv - The address environment to be modified.
|
||||||
|
* addr - Base address of the region.
|
||||||
|
* len - Size of the region.
|
||||||
|
* prot - Access right flags.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Zero (OK) on success; a negated errno value on failure.
|
* 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
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
int up_addrenv_text_enable_write(FAR group_addrenv_t *addrenv);
|
int up_addrenv_mprot(group_addrenv_t *addrenv, uintptr_t addr, size_t len,
|
||||||
#endif
|
int prot);
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* 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);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
Reference in New Issue
Block a user