Sandbox concept refinements.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12980 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
a2e373d78d
commit
6de7825d13
|
@ -49,33 +49,39 @@ static THD_WORKING_AREA(waUnprivileged1, 128);
|
|||
static THD_FUNCTION(Unprivileged1, arg) {
|
||||
extern uint32_t __flash7_start__, __flash7_end__,
|
||||
__ram7_start__, __ram7_end__;
|
||||
static const sb_regions_t regions = {
|
||||
static const sb_config_t sb_config = {
|
||||
.r0_base = (uint32_t)&__flash7_start__,
|
||||
.r0_end = (uint32_t)&__flash7_end__,
|
||||
.r1_base = (uint32_t)&__ram7_start__,
|
||||
.r1_end = (uint32_t)&__ram7_end__
|
||||
};
|
||||
sb_class_t sbx1;
|
||||
|
||||
(void)arg;
|
||||
chRegSetThreadName("unprivileged");
|
||||
|
||||
/* MPU setup for the sandbox, both regions are used because it is
|
||||
flash code.*/
|
||||
/* Sandbox object initialization.*/
|
||||
sbObjectInit(&sbx1);
|
||||
|
||||
/* Static MPU setup for the sandbox, both regions are used because in this
|
||||
demo it requires both a flash and a RAM regions.*/
|
||||
mpuConfigureRegion(MPU_REGION_0,
|
||||
regions.r0_base,
|
||||
sb_config.r0_base,
|
||||
MPU_RASR_ATTR_AP_RO_RO |
|
||||
MPU_RASR_ATTR_CACHEABLE_WT_NWA |
|
||||
MPU_RASR_SIZE_16K |
|
||||
MPU_RASR_ENABLE);
|
||||
mpuConfigureRegion(MPU_REGION_1,
|
||||
regions.r1_base,
|
||||
sb_config.r1_base,
|
||||
MPU_RASR_ATTR_AP_RW_RW |
|
||||
MPU_RASR_ATTR_CACHEABLE_WB_WA |
|
||||
MPU_RASR_SIZE_4K |
|
||||
MPU_RASR_ENABLE);
|
||||
|
||||
sbStart((const sb_header_t *)&__flash7_start__, ®ions);
|
||||
chSysHalt("it returned");
|
||||
/* This thread goes in the sandbox and is trapped there, it cannot
|
||||
return, only invoke the sandbox API.*/
|
||||
sbStart(&sbx1, &sb_config);
|
||||
chSysHalt("zombies");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -104,8 +110,8 @@ int main(void) {
|
|||
|
||||
/* Creating the unprivileged thread.*/
|
||||
chprintf((BaseSequentialStream *)&SD2, "Starting unprivileged thread\r\n");
|
||||
tp = chThdCreateStatic(waUnprivileged1, sizeof(waUnprivileged1), NORMALPRIO - 10U,
|
||||
Unprivileged1, NULL);
|
||||
tp = chThdCreateStatic(waUnprivileged1, sizeof(waUnprivileged1),
|
||||
NORMALPRIO - 10U, Unprivileged1, NULL);
|
||||
|
||||
/* Waiting for the unprivileged thread to exit or fail.*/
|
||||
msg = chThdWait(tp);
|
||||
|
|
|
@ -129,16 +129,27 @@ uint32_t sb_undef_handler(struct port_extctx *ectxp) {
|
|||
return SB_ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sandbox object initialization.
|
||||
*/
|
||||
void sbObjectInit(sb_class_t *sbcp) {
|
||||
|
||||
sbcp->config = NULL;
|
||||
sbcp->tp = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts a sandboxed thread.
|
||||
*
|
||||
* @param[in] sbhp pointer to the sandbox binary header
|
||||
* @param[in] rp pointer to the regions descriptor
|
||||
* @param[in] sbcp pointer to the sandbox configuration structure
|
||||
* @return The function returns only if the operation failed.
|
||||
*/
|
||||
void sbStart(const sb_header_t *sbhp,
|
||||
const sb_regions_t *rp) {
|
||||
void sbStart(sb_class_t * sbcp, const sb_config_t *config) {
|
||||
uint32_t pc, psp;
|
||||
const sb_header_t *sbhp;
|
||||
|
||||
/* The header is conventionally placed at base of region zero.*/
|
||||
sbhp = (const sb_header_t *)config->r0_base;
|
||||
|
||||
/* Checking header magic numbers.*/
|
||||
if ((sbhp->hdr_magic1 != SB_MAGIC1) || (sbhp->hdr_magic2 != SB_MAGIC2)) {
|
||||
|
@ -151,8 +162,8 @@ void sbStart(const sb_header_t *sbhp,
|
|||
}
|
||||
|
||||
/* Checking regions, applet regions and sandbox regions must match.*/
|
||||
if ((sbhp->r0_base != rp->r0_base) || (sbhp->r0_end != rp->r0_end) ||
|
||||
(sbhp->r1_base != rp->r1_base) || (sbhp->r1_end != rp->r1_end)) {
|
||||
if ((sbhp->r0_base != config->r0_base) || (sbhp->r0_end != config->r0_end) ||
|
||||
(sbhp->r1_base != config->r1_base) || (sbhp->r1_end != config->r1_end)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -160,17 +171,18 @@ void sbStart(const sb_header_t *sbhp,
|
|||
pc = (sbhp->r0_base + sbhp->hdr_size) | 1U;
|
||||
|
||||
/* PSP initial address, it is placed at end of the last region.*/
|
||||
if (rp->r1_base == 0U) {
|
||||
if (config->r1_base == 0U) {
|
||||
/* Must be in region 1.*/
|
||||
psp = rp->r0_end;
|
||||
psp = config->r0_end;
|
||||
}
|
||||
else {
|
||||
/* Must be in region 2.*/
|
||||
psp = rp->r1_end;
|
||||
psp = config->r1_end;
|
||||
}
|
||||
|
||||
/* Additional context information.*/
|
||||
chThdGetSelfX()->ctx.syscall.p = (const void *)rp;
|
||||
sbcp->config = config;
|
||||
chThdGetSelfX()->ctx.syscall.p = (const void *)sbcp;
|
||||
chThdGetSelfX()->ctx.syscall.psp = (regarm_t)__get_PSP();
|
||||
|
||||
/* Jumping to the unprivileged code.*/
|
||||
|
|
|
@ -97,7 +97,21 @@ typedef struct {
|
|||
* @note Zero if not used.
|
||||
*/
|
||||
uint32_t r1_end;
|
||||
} sb_regions_t;
|
||||
} sb_config_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a sandbox object.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Pointer to the sandbox configuration data.
|
||||
*/
|
||||
const sb_config_t *config;
|
||||
/**
|
||||
* @brief Thread running in the sandbox.
|
||||
*/
|
||||
thread_t *tp;
|
||||
} sb_class_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a sandbox applet headers.
|
||||
|
@ -925,8 +939,8 @@ typedef struct {
|
|||
extern "C" {
|
||||
#endif
|
||||
void port_syscall(struct port_extctx *ctxp, uint32_t n);
|
||||
void sbStart(const sb_header_t *sbhp,
|
||||
const sb_regions_t *rp);
|
||||
void sbObjectInit(sb_class_t *sbcp);
|
||||
void sbStart(sb_class_t *sbcp, const sb_config_t *config);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue