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:
Giovanni Di Sirio 2019-09-11 12:53:31 +00:00
parent a2e373d78d
commit 6de7825d13
3 changed files with 54 additions and 22 deletions

View File

@ -49,33 +49,39 @@ static THD_WORKING_AREA(waUnprivileged1, 128);
static THD_FUNCTION(Unprivileged1, arg) { static THD_FUNCTION(Unprivileged1, arg) {
extern uint32_t __flash7_start__, __flash7_end__, extern uint32_t __flash7_start__, __flash7_end__,
__ram7_start__, __ram7_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_base = (uint32_t)&__flash7_start__,
.r0_end = (uint32_t)&__flash7_end__, .r0_end = (uint32_t)&__flash7_end__,
.r1_base = (uint32_t)&__ram7_start__, .r1_base = (uint32_t)&__ram7_start__,
.r1_end = (uint32_t)&__ram7_end__ .r1_end = (uint32_t)&__ram7_end__
}; };
sb_class_t sbx1;
(void)arg; (void)arg;
chRegSetThreadName("unprivileged"); chRegSetThreadName("unprivileged");
/* MPU setup for the sandbox, both regions are used because it is /* Sandbox object initialization.*/
flash code.*/ 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, mpuConfigureRegion(MPU_REGION_0,
regions.r0_base, sb_config.r0_base,
MPU_RASR_ATTR_AP_RO_RO | MPU_RASR_ATTR_AP_RO_RO |
MPU_RASR_ATTR_CACHEABLE_WT_NWA | MPU_RASR_ATTR_CACHEABLE_WT_NWA |
MPU_RASR_SIZE_16K | MPU_RASR_SIZE_16K |
MPU_RASR_ENABLE); MPU_RASR_ENABLE);
mpuConfigureRegion(MPU_REGION_1, mpuConfigureRegion(MPU_REGION_1,
regions.r1_base, sb_config.r1_base,
MPU_RASR_ATTR_AP_RW_RW | MPU_RASR_ATTR_AP_RW_RW |
MPU_RASR_ATTR_CACHEABLE_WB_WA | MPU_RASR_ATTR_CACHEABLE_WB_WA |
MPU_RASR_SIZE_4K | MPU_RASR_SIZE_4K |
MPU_RASR_ENABLE); MPU_RASR_ENABLE);
sbStart((const sb_header_t *)&__flash7_start__, &regions); /* This thread goes in the sandbox and is trapped there, it cannot
chSysHalt("it returned"); return, only invoke the sandbox API.*/
sbStart(&sbx1, &sb_config);
chSysHalt("zombies");
} }
/* /*
@ -104,8 +110,8 @@ int main(void) {
/* Creating the unprivileged thread.*/ /* Creating the unprivileged thread.*/
chprintf((BaseSequentialStream *)&SD2, "Starting unprivileged thread\r\n"); chprintf((BaseSequentialStream *)&SD2, "Starting unprivileged thread\r\n");
tp = chThdCreateStatic(waUnprivileged1, sizeof(waUnprivileged1), NORMALPRIO - 10U, tp = chThdCreateStatic(waUnprivileged1, sizeof(waUnprivileged1),
Unprivileged1, NULL); NORMALPRIO - 10U, Unprivileged1, NULL);
/* Waiting for the unprivileged thread to exit or fail.*/ /* Waiting for the unprivileged thread to exit or fail.*/
msg = chThdWait(tp); msg = chThdWait(tp);

View File

@ -129,16 +129,27 @@ uint32_t sb_undef_handler(struct port_extctx *ectxp) {
return SB_ERR_NOT_IMPLEMENTED; 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. * @brief Starts a sandboxed thread.
* *
* @param[in] sbhp pointer to the sandbox binary header * @param[in] sbcp pointer to the sandbox configuration structure
* @param[in] rp pointer to the regions descriptor
* @return The function returns only if the operation failed. * @return The function returns only if the operation failed.
*/ */
void sbStart(const sb_header_t *sbhp, void sbStart(sb_class_t * sbcp, const sb_config_t *config) {
const sb_regions_t *rp) {
uint32_t pc, psp; 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.*/ /* Checking header magic numbers.*/
if ((sbhp->hdr_magic1 != SB_MAGIC1) || (sbhp->hdr_magic2 != SB_MAGIC2)) { 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.*/ /* Checking regions, applet regions and sandbox regions must match.*/
if ((sbhp->r0_base != rp->r0_base) || (sbhp->r0_end != rp->r0_end) || if ((sbhp->r0_base != config->r0_base) || (sbhp->r0_end != config->r0_end) ||
(sbhp->r1_base != rp->r1_base) || (sbhp->r1_end != rp->r1_end)) { (sbhp->r1_base != config->r1_base) || (sbhp->r1_end != config->r1_end)) {
return; return;
} }
@ -160,17 +171,18 @@ void sbStart(const sb_header_t *sbhp,
pc = (sbhp->r0_base + sbhp->hdr_size) | 1U; pc = (sbhp->r0_base + sbhp->hdr_size) | 1U;
/* PSP initial address, it is placed at end of the last region.*/ /* 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.*/ /* Must be in region 1.*/
psp = rp->r0_end; psp = config->r0_end;
} }
else { else {
/* Must be in region 2.*/ /* Must be in region 2.*/
psp = rp->r1_end; psp = config->r1_end;
} }
/* Additional context information.*/ /* 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(); chThdGetSelfX()->ctx.syscall.psp = (regarm_t)__get_PSP();
/* Jumping to the unprivileged code.*/ /* Jumping to the unprivileged code.*/

View File

@ -97,7 +97,21 @@ typedef struct {
* @note Zero if not used. * @note Zero if not used.
*/ */
uint32_t r1_end; 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. * @brief Type of a sandbox applet headers.
@ -925,8 +939,8 @@ typedef struct {
extern "C" { extern "C" {
#endif #endif
void port_syscall(struct port_extctx *ctxp, uint32_t n); void port_syscall(struct port_extctx *ctxp, uint32_t n);
void sbStart(const sb_header_t *sbhp, void sbObjectInit(sb_class_t *sbcp);
const sb_regions_t *rp); void sbStart(sb_class_t *sbcp, const sb_config_t *config);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif