Added sbExec() function.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15358 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
c65d695093
commit
c1ee7b08b5
|
@ -55,7 +55,7 @@ endif
|
|||
# Stack size to be allocated to the Cortex-M process stack. This stack is
|
||||
# the stack used by the main() thread.
|
||||
ifeq ($(USE_PROCESS_STACKSIZE),)
|
||||
USE_PROCESS_STACKSIZE = 0x400
|
||||
USE_PROCESS_STACKSIZE = 0x800
|
||||
endif
|
||||
|
||||
# Stack size to the allocated to the Cortex-M main/exceptions stack. This
|
||||
|
|
|
@ -107,7 +107,7 @@ static const char *sbx1_envp[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
static THD_WORKING_AREA(waUnprivileged1, 1024);
|
||||
static THD_WORKING_AREA(waUnprivileged1, 2048);
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Main and generic code. */
|
||||
|
@ -245,9 +245,9 @@ int main(void) {
|
|||
if (CH_RET_IS_ERROR(ret)) {
|
||||
chSysHalt("VFS");
|
||||
}
|
||||
sbPosixRegisterDescriptor(&sbx1, STDIN_FILENO, (vfs_node_c *)roAddRef(np));
|
||||
sbPosixRegisterDescriptor(&sbx1, STDOUT_FILENO, (vfs_node_c *)roAddRef(np));
|
||||
sbPosixRegisterDescriptor(&sbx1, STDERR_FILENO, (vfs_node_c *)roAddRef(np));
|
||||
sbRegisterDescriptor(&sbx1, STDIN_FILENO, (vfs_node_c *)roAddRef(np));
|
||||
sbRegisterDescriptor(&sbx1, STDOUT_FILENO, (vfs_node_c *)roAddRef(np));
|
||||
sbRegisterDescriptor(&sbx1, STDERR_FILENO, (vfs_node_c *)roAddRef(np));
|
||||
vfsClose(np);
|
||||
|
||||
#if 0
|
||||
|
@ -259,9 +259,9 @@ int main(void) {
|
|||
if (CH_RET_IS_ERROR(ret)) {
|
||||
chSysHalt("VFS");
|
||||
}
|
||||
sbPosixRegisterDescriptor(&sbx2, STDIN_FILENO, (vfs_node_c *)roAddRef(np));
|
||||
sbPosixRegisterDescriptor(&sbx2, STDOUT_FILENO, (vfs_node_c *)roAddRef(np));
|
||||
sbPosixRegisterDescriptor(&sbx2, STDERR_FILENO, (vfs_node_c *)roAddRef(np));
|
||||
sbRegisterDescriptor(&sbx2, STDIN_FILENO, (vfs_node_c *)roAddRef(np));
|
||||
sbRegisterDescriptor(&sbx2, STDOUT_FILENO, (vfs_node_c *)roAddRef(np));
|
||||
sbRegisterDescriptor(&sbx2, STDERR_FILENO, (vfs_node_c *)roAddRef(np));
|
||||
vfsClose(np);
|
||||
#endif
|
||||
|
||||
|
@ -299,29 +299,15 @@ int main(void) {
|
|||
if (palReadLine(LINE_BUTTON)) {
|
||||
if (!sbIsThreadRunningX(&sbx1)) {
|
||||
|
||||
/* Loading sandbox code.*/
|
||||
ret = sbElfLoadFile((vfs_driver_c *)&sb1_root_overlay_driver,
|
||||
"/bin/msh.elf",
|
||||
&sbx1.config->regions[0].area);
|
||||
/* Running the sandbox.*/
|
||||
ret = sbExec(&sbx1, "/bin/msh.elf",
|
||||
waUnprivileged1, sizeof (waUnprivileged1), NORMALPRIO - 1,
|
||||
sbx1_argv, sbx1_envp);
|
||||
if (CH_RET_IS_ERROR(ret)) {
|
||||
chSysHalt("ELF");
|
||||
}
|
||||
|
||||
/* Starting sandboxed thread 1.*/
|
||||
if (sbStartThread(&sbx1, "sbx1",
|
||||
waUnprivileged1, sizeof (waUnprivileged1), NORMALPRIO - 1,
|
||||
sbx1_argv, sbx1_envp) == NULL) {
|
||||
chSysHalt("sbx1 failed");
|
||||
chprintf((BaseSequentialStream *)&SD2, "SBX1 launch failed (%08lx)\r\n", ret);
|
||||
chThdSleepMilliseconds(1000);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
static uint8_t loadbuf[1024];
|
||||
static memory_area_t ma = {loadbuf, sizeof (loadbuf)};
|
||||
ret = sbElfLoadFile((vfs_driver_c *)&sb1_root_overlay_driver, "/bin/app.elf", &ma);
|
||||
if (CH_RET_IS_ERROR(ret)) {
|
||||
chSysHalt("ELF");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,34 +105,34 @@ void sb_strv_copy(const char *sp[], void *dp, int n) {
|
|||
*(vp + n) = NULL;
|
||||
}
|
||||
|
||||
bool sb_is_valid_read_range(sb_class_t *sbcp, const void *start, size_t size) {
|
||||
const sb_memory_region_t *rp = &sbcp->config->regions[0];
|
||||
bool sb_is_valid_read_range(sb_class_t *sbp, const void *start, size_t size) {
|
||||
const sb_memory_region_t *rp = &sbp->config->regions[0];
|
||||
|
||||
do {
|
||||
if (rp->used && chMemIsSpaceWithinX(&rp->area, start, size)) {
|
||||
return true;
|
||||
}
|
||||
rp++;
|
||||
} while (rp < &sbcp->config->regions[SB_CFG_NUM_REGIONS]);
|
||||
} while (rp < &sbp->config->regions[SB_CFG_NUM_REGIONS]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sb_is_valid_write_range(sb_class_t *sbcp, void *start, size_t size) {
|
||||
const sb_memory_region_t *rp = &sbcp->config->regions[0];
|
||||
bool sb_is_valid_write_range(sb_class_t *sbp, void *start, size_t size) {
|
||||
const sb_memory_region_t *rp = &sbp->config->regions[0];
|
||||
|
||||
do {
|
||||
if (rp->used && chMemIsSpaceWithinX(&rp->area, start, size)) {
|
||||
return rp->writeable;
|
||||
}
|
||||
rp++;
|
||||
} while (rp < &sbcp->config->regions[SB_CFG_NUM_REGIONS]);
|
||||
} while (rp < &sbp->config->regions[SB_CFG_NUM_REGIONS]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t sb_check_string(sb_class_t *sbcp, const char *s, size_t max) {
|
||||
const sb_memory_region_t *rp = &sbcp->config->regions[0];
|
||||
size_t sb_check_string(sb_class_t *sbp, const char *s, size_t max) {
|
||||
const sb_memory_region_t *rp = &sbp->config->regions[0];
|
||||
|
||||
do {
|
||||
if (rp->used) {
|
||||
|
@ -142,13 +142,13 @@ size_t sb_check_string(sb_class_t *sbcp, const char *s, size_t max) {
|
|||
}
|
||||
}
|
||||
rp++;
|
||||
} while (rp < &sbcp->config->regions[SB_CFG_NUM_REGIONS]);
|
||||
} while (rp < &sbp->config->regions[SB_CFG_NUM_REGIONS]);
|
||||
|
||||
return (size_t)0;
|
||||
}
|
||||
|
||||
size_t sb_check_pointers_array(sb_class_t *sbcp, const void *pp[], size_t max) {
|
||||
const sb_memory_region_t *rp = &sbcp->config->regions[0];
|
||||
size_t sb_check_pointers_array(sb_class_t *sbp, const void *pp[], size_t max) {
|
||||
const sb_memory_region_t *rp = &sbp->config->regions[0];
|
||||
|
||||
do {
|
||||
if (rp->used) {
|
||||
|
@ -158,21 +158,21 @@ size_t sb_check_pointers_array(sb_class_t *sbcp, const void *pp[], size_t max) {
|
|||
}
|
||||
}
|
||||
rp++;
|
||||
} while (rp < &sbcp->config->regions[SB_CFG_NUM_REGIONS]);
|
||||
} while (rp < &sbp->config->regions[SB_CFG_NUM_REGIONS]);
|
||||
|
||||
return (size_t)0;
|
||||
}
|
||||
|
||||
size_t sb_check_strings_array(sb_class_t *sbcp, const char *pp[], size_t max) {
|
||||
size_t sb_check_strings_array(sb_class_t *sbp, const char *pp[], size_t max) {
|
||||
const char *s;
|
||||
size_t n;
|
||||
|
||||
n = sb_check_pointers_array(sbcp, (const void **)pp, max);
|
||||
n = sb_check_pointers_array(sbp, (const void **)pp, max);
|
||||
if (n > (size_t)0) {
|
||||
while ((s = *pp++) != NULL) {
|
||||
size_t sn;
|
||||
|
||||
sn = sb_check_string(sbcp, s, max - n);
|
||||
sn = sb_check_string(sbp, s, max - n);
|
||||
if (sn == (size_t)0) {
|
||||
return (size_t)0;
|
||||
}
|
||||
|
@ -187,27 +187,27 @@ size_t sb_check_strings_array(sb_class_t *sbcp, const char *pp[], size_t max) {
|
|||
/**
|
||||
* @brief Sandbox object initialization.
|
||||
*
|
||||
* @param[out] sbcp pointer to the sandbox object
|
||||
* @param[out] sbp pointer to the sandbox object
|
||||
* @param[in] config pointer to the sandbox configuration
|
||||
*
|
||||
* @init
|
||||
*/
|
||||
void sbObjectInit(sb_class_t *sbcp, const sb_config_t *config) {
|
||||
void sbObjectInit(sb_class_t *sbp, const sb_config_t *config) {
|
||||
|
||||
sbcp->config = config;
|
||||
sbcp->tp = NULL;
|
||||
sbp->config = config;
|
||||
sbp->tp = NULL;
|
||||
#if CH_CFG_USE_MESSAGES == TRUE
|
||||
sbcp->msg_tp = NULL;
|
||||
sbp->msg_tp = NULL;
|
||||
#endif
|
||||
#if CH_CFG_USE_EVENTS == TRUE
|
||||
chEvtObjectInit(&sbcp->es);
|
||||
chEvtObjectInit(&sbp->es);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts a sandboxed thread.
|
||||
*
|
||||
* @param[in] sbcp pointer to a @p sb_class_t structure
|
||||
* @param[in] sbp pointer to a @p sb_class_t structure
|
||||
* @param[in] name name to be assigned to the thread
|
||||
* @param[out] wsp pointer to a working area dedicated to the thread stack
|
||||
* @param[in] size size of the working area
|
||||
|
@ -217,12 +217,12 @@ void sbObjectInit(sb_class_t *sbcp, const sb_config_t *config) {
|
|||
* @return The thread pointer.
|
||||
* @retval NULL if the sandbox thread creation failed.
|
||||
*/
|
||||
thread_t *sbStartThread(sb_class_t *sbcp, const char *name,
|
||||
thread_t *sbStartThread(sb_class_t *sbp, const char *name,
|
||||
void *wsp, size_t size, tprio_t prio,
|
||||
const char *argv[], const char *envp[]) {
|
||||
thread_t *utp;
|
||||
const sb_header_t *sbhp;
|
||||
const sb_config_t *config = sbcp->config;
|
||||
const sb_config_t *config = sbp->config;
|
||||
void *usp, *uargv, *uenvp;
|
||||
size_t envsize, argsize, parsize;
|
||||
int uargc, uenvc;
|
||||
|
@ -290,7 +290,7 @@ thread_t *sbStartThread(sb_class_t *sbcp, const char *name,
|
|||
.prio = prio,
|
||||
.u_pc = sbhp->hdr_entry,
|
||||
.u_psp = (uint32_t)usp,
|
||||
.arg = (void *)sbcp
|
||||
.arg = (void *)sbp
|
||||
};
|
||||
#if PORT_SWITCHED_REGIONS_NUMBER > 0
|
||||
for (unsigned i = 0U; i < PORT_SWITCHED_REGIONS_NUMBER; i++) {
|
||||
|
@ -301,7 +301,7 @@ thread_t *sbStartThread(sb_class_t *sbcp, const char *name,
|
|||
utp = chThdCreateUnprivileged(&utd);
|
||||
|
||||
/* For messages exchange.*/
|
||||
sbcp->tp = utp;
|
||||
sbp->tp = utp;
|
||||
|
||||
return utp;
|
||||
}
|
||||
|
@ -309,20 +309,149 @@ thread_t *sbStartThread(sb_class_t *sbcp, const char *name,
|
|||
/**
|
||||
* @brief Verifies if the sandbox thread is running.
|
||||
*
|
||||
* @param[in] sbcp pointer to a @p sb_class_t structure
|
||||
* @param[in] sbp pointer to a @p sb_class_t structure
|
||||
* @return The thread status.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
bool sbIsThreadRunningX(sb_class_t *sbcp) {
|
||||
bool sbIsThreadRunningX(sb_class_t *sbp) {
|
||||
|
||||
if (sbcp->tp == NULL) {
|
||||
if (sbp->tp == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !chThdTerminatedX(sbcp->tp);
|
||||
return !chThdTerminatedX(sbp->tp);
|
||||
}
|
||||
|
||||
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Execute an elf file within a sandbox.
|
||||
* @note The file is loaded into region zero of the sandbox which is
|
||||
* assumed to be used for both code and data, extra regions are
|
||||
* not touched by this function.
|
||||
*
|
||||
* @param[in] sbp pointer to a @p sb_class_t structure
|
||||
* @param[in] pathname file to be executed
|
||||
* @param[in] argv arguments to be passed to the sandbox
|
||||
* @param[in] envp environment variables to be passed to the sandbox
|
||||
* @return The operation result.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
msg_t sbExec(sb_class_t *sbp, const char *pathname,
|
||||
void *wsp, size_t size, tprio_t prio,
|
||||
const char *argv[], const char *envp[]) {
|
||||
const sb_config_t *config = sbp->config;
|
||||
memory_area_t ma = config->regions[0].area;
|
||||
const sb_header_t *sbhp;
|
||||
msg_t ret;
|
||||
void *usp, *uargv, *uenvp;
|
||||
size_t envsize, argsize, parsize;
|
||||
int uargc, uenvc;
|
||||
|
||||
/* Setting up an initial stack for the sandbox.*/
|
||||
usp = (void *)(config->regions[0].area.base + config->regions[0].area.size);
|
||||
|
||||
/* Allocating space for environment variables.*/
|
||||
envsize = sb_strv_getsize(envp, &uenvc);
|
||||
PUSHSPACE(usp, envsize);
|
||||
uenvp = usp;
|
||||
|
||||
/* Allocating space for arguments.*/
|
||||
argsize = sb_strv_getsize(argv, &uargc);
|
||||
PUSHSPACE(usp, argsize);
|
||||
uargv = usp;
|
||||
|
||||
/* Allocating space for parameters.*/
|
||||
if (MEM_IS_ALIGNED(usp, PORT_STACK_ALIGN)) {
|
||||
parsize = sizeof (int) + sizeof (const char **) + sizeof (const char **) + sizeof (int);
|
||||
}
|
||||
else {
|
||||
parsize = sizeof (const char **) + sizeof (const char **) + sizeof (int);
|
||||
}
|
||||
PUSHSPACE(usp, parsize);
|
||||
|
||||
/* Checking stack allocation.*/
|
||||
if (!chMemIsSpaceWithinX(&config->regions[0].area,
|
||||
usp, envsize + argsize + parsize)) {
|
||||
return CH_RET_ENOMEM;
|
||||
}
|
||||
|
||||
/* Adjusting the size of the memory area object, we don't want the loaded
|
||||
elf file to overwrite the initialized stack.*/
|
||||
ma.size -= envsize + argsize + parsize;
|
||||
|
||||
/* Initializing stack.*/
|
||||
sb_strv_copy(envp, uenvp, uenvc);
|
||||
sb_strv_copy(argv, uargv, uargc);
|
||||
*((uint32_t *)usp + 2) = (uint32_t)uenvp;
|
||||
*((uint32_t *)usp + 1) = (uint32_t)uargv;
|
||||
*((uint32_t *)usp + 0) = (uint32_t)uargc;
|
||||
|
||||
/* Loading sandbox code into the specified memory area.*/
|
||||
ret = sbElfLoadFile(config->vfs_driver, pathname, &ma);
|
||||
CH_RETURN_ON_ERROR(ret);
|
||||
|
||||
/* Header location.*/
|
||||
sbhp = (const sb_header_t *)(void *)ma.base;
|
||||
|
||||
/* Checking header magic numbers.*/
|
||||
if ((sbhp->hdr_magic1 != SB_MAGIC1) || (sbhp->hdr_magic2 != SB_MAGIC2)) {
|
||||
return CH_RET_ENOEXEC;
|
||||
}
|
||||
|
||||
/* Checking header size.*/
|
||||
if (sbhp->hdr_size != sizeof (sb_header_t)) {
|
||||
return CH_RET_ENOEXEC;
|
||||
}
|
||||
|
||||
/* Checking header entry point.*/
|
||||
if (!chMemIsSpaceWithinX(&ma, (const void *)sbhp->hdr_entry, (size_t)2)) {
|
||||
return CH_RET_EFAULT;
|
||||
}
|
||||
|
||||
/* Everything OK, starting the unprivileged thread inside the sandbox.*/
|
||||
unprivileged_thread_descriptor_t utd = {
|
||||
.name = pathname,
|
||||
.wbase = (stkalign_t *)wsp,
|
||||
.wend = (stkalign_t *)wsp + (size / sizeof (stkalign_t)),
|
||||
.prio = prio,
|
||||
.u_pc = sbhp->hdr_entry,
|
||||
.u_psp = (uint32_t)usp,
|
||||
.arg = (void *)sbp
|
||||
};
|
||||
#if PORT_SWITCHED_REGIONS_NUMBER > 0
|
||||
for (unsigned i = 0U; i < PORT_SWITCHED_REGIONS_NUMBER; i++) {
|
||||
utd.regions[i] = config->mpuregs[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
sbp->tp = chThdCreateUnprivileged(&utd);
|
||||
|
||||
if (sbp->tp == NULL) {
|
||||
return CH_RET_ENOMEM;
|
||||
}
|
||||
|
||||
return CH_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Registers a file descriptor on a sandbox.
|
||||
*
|
||||
* @param[in] sbp pointer to a @p sb_class_t structure
|
||||
* @param[in] fd file descriptor to be assigned
|
||||
* @param[in] np VFS node to be registered on the file descriptor
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void sbRegisterDescriptor(sb_class_t *sbp, int fd, vfs_node_c *np) {
|
||||
|
||||
chDbgAssert(sb_is_available_descriptor(&sbp->io, fd), "invalid file descriptor");
|
||||
|
||||
sbp->io.vfs_nodes[fd] = np;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (CH_CFG_USE_WAITEXIT == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Blocks the execution of the invoking thread until the specified
|
||||
|
@ -330,21 +459,21 @@ bool sbIsThreadRunningX(sb_class_t *sbcp) {
|
|||
* @pre The configuration option @p CH_CFG_USE_WAITEXIT must be enabled in
|
||||
* order to use this function.
|
||||
*
|
||||
* @param[in] sbcp pointer to a @p sb_class_t structure
|
||||
* @param[in] sbp pointer to a @p sb_class_t structure
|
||||
* @return The exit code from the terminated sandbox thread.
|
||||
* @retval MSG_RESET Sandbox thread not started.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
msg_t sbWaitThread(sb_class_t *sbcp) {
|
||||
msg_t sbWaitThread(sb_class_t *sbp) {
|
||||
msg_t msg;
|
||||
|
||||
if (sbcp->tp == NULL) {
|
||||
if (sbp->tp == NULL) {
|
||||
return MSG_RESET;
|
||||
}
|
||||
|
||||
msg = chThdWait(sbcp->tp);
|
||||
sbcp->tp = NULL;
|
||||
msg = chThdWait(sbp->tp);
|
||||
sbp->tp = NULL;
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
@ -354,7 +483,7 @@ msg_t sbWaitThread(sb_class_t *sbcp) {
|
|||
/**
|
||||
* @brief Sends a message to a sandboxed thread.
|
||||
*
|
||||
* @param[in] sbcp pointer to the sandbox object
|
||||
* @param[in] sbp pointer to the sandbox object
|
||||
* @param[in] msg message to be sent
|
||||
* @param[in] timeout the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
|
@ -367,28 +496,28 @@ msg_t sbWaitThread(sb_class_t *sbcp) {
|
|||
*
|
||||
* @api
|
||||
*/
|
||||
msg_t sbSendMessageTimeout(sb_class_t *sbcp,
|
||||
msg_t sbSendMessageTimeout(sb_class_t *sbp,
|
||||
msg_t msg,
|
||||
sysinterval_t timeout) {
|
||||
thread_t *ctp = __sch_get_currthread();
|
||||
|
||||
chDbgCheck(sbcp != NULL);
|
||||
chDbgCheck(sbp != NULL);
|
||||
|
||||
chSysLock();
|
||||
|
||||
/* Sending the message.*/
|
||||
ctp->u.sentmsg = msg;
|
||||
__ch_msg_insert(&sbcp->tp->msgqueue, ctp);
|
||||
if (sbcp->tp->state == CH_STATE_WTMSG) {
|
||||
(void) chSchReadyI(sbcp->tp);
|
||||
__ch_msg_insert(&sbp->tp->msgqueue, ctp);
|
||||
if (sbp->tp->state == CH_STATE_WTMSG) {
|
||||
(void) chSchReadyI(sbp->tp);
|
||||
}
|
||||
msg = chSchGoSleepTimeoutS(CH_STATE_SNDMSGQ, timeout);
|
||||
|
||||
/* If a timeout occurred while the boxed thread already received the message
|
||||
then this thread needs to "unregister" as sender, the boxed error will
|
||||
get SB_ERR_EBUSY when/if trying to reply.*/
|
||||
if ((msg == MSG_TIMEOUT) && (sbcp->msg_tp == ctp)) {
|
||||
sbcp->msg_tp = NULL;
|
||||
if ((msg == MSG_TIMEOUT) && (sbp->msg_tp == ctp)) {
|
||||
sbp->msg_tp = NULL;
|
||||
}
|
||||
|
||||
chSysUnlock();
|
||||
|
|
|
@ -93,21 +93,28 @@ extern "C" {
|
|||
#endif
|
||||
void port_syscall(struct port_extctx *ctxp, uint32_t n);
|
||||
size_t sb_strv_getsize(const char *v[], int *np);
|
||||
bool sb_is_valid_read_range(sb_class_t *sbcp, const void *start, size_t size);
|
||||
bool sb_is_valid_write_range(sb_class_t *sbcp, void *start, size_t size);
|
||||
size_t sb_check_string(sb_class_t *sbcp, const char *s, size_t max);
|
||||
size_t sb_check_pointers_array(sb_class_t *sbcp, const void *pp[], size_t max);
|
||||
size_t sb_check_strings_array(sb_class_t *sbcp, const char *pp[], size_t max);
|
||||
void sbObjectInit(sb_class_t *sbcp, const sb_config_t *config);
|
||||
thread_t *sbStartThread(sb_class_t *sbcp, const char *name,
|
||||
void sb_strv_copy(const char *sp[], void *dp, int n);
|
||||
bool sb_is_valid_read_range(sb_class_t *sbp, const void *start, size_t size);
|
||||
bool sb_is_valid_write_range(sb_class_t *sbp, void *start, size_t size);
|
||||
size_t sb_check_string(sb_class_t *sbp, const char *s, size_t max);
|
||||
size_t sb_check_pointers_array(sb_class_t *sbp, const void *pp[], size_t max);
|
||||
size_t sb_check_strings_array(sb_class_t *sbp, const char *pp[], size_t max);
|
||||
void sbObjectInit(sb_class_t *sbp, const sb_config_t *config);
|
||||
thread_t *sbStartThread(sb_class_t *sbp, const char *name,
|
||||
void *wsp, size_t size, tprio_t prio,
|
||||
const char *argv[], const char *envp[]);
|
||||
bool sbIsThreadRunningX(sb_class_t *sbcp);
|
||||
bool sbIsThreadRunningX(sb_class_t *sbp);
|
||||
#if SB_CFG_ENABLE_VFS == TRUE
|
||||
msg_t sbExec(sb_class_t *sbp, const char *pathname,
|
||||
void *wsp, size_t size, tprio_t prio,
|
||||
const char *argv[], const char *envp[]);
|
||||
void sbRegisterDescriptor(sb_class_t *sbp, int fd, vfs_node_c *np);
|
||||
#endif
|
||||
#if CH_CFG_USE_WAITEXIT == TRUE
|
||||
msg_t sbWaitThread(sb_class_t *sbcp);
|
||||
msg_t sbWaitThread(sb_class_t *sbp);
|
||||
#endif
|
||||
#if CH_CFG_USE_MESSAGES == TRUE
|
||||
msg_t sbSendMessageTimeout(sb_class_t *sbcp,
|
||||
msg_t sbSendMessageTimeout(sb_class_t *sbp,
|
||||
msg_t msg,
|
||||
sysinterval_t timeout);
|
||||
#endif
|
||||
|
@ -135,7 +142,7 @@ static inline void sbHostInit(void) {
|
|||
/**
|
||||
* @brief Sends a message to a sandboxed thread.
|
||||
*
|
||||
* @param[in] sbcp pointer to the sandbox object
|
||||
* @param[in] sbp pointer to the sandbox object
|
||||
* @param[in] msg message to be sent
|
||||
* @return The returned message.
|
||||
* @retval MSG_RESET if the exchange aborted, sandboxed thread API usage
|
||||
|
@ -143,9 +150,9 @@ static inline void sbHostInit(void) {
|
|||
*
|
||||
* @api
|
||||
*/
|
||||
static inline msg_t sbSendMessage(sb_class_t *sbcp, msg_t msg) {
|
||||
static inline msg_t sbSendMessage(sb_class_t *sbp, msg_t msg) {
|
||||
|
||||
return sbSendMessageTimeout(sbcp, msg, TIME_INFINITE);
|
||||
return sbSendMessageTimeout(sbp, msg, TIME_INFINITE);
|
||||
}
|
||||
#endif /* CH_CFG_USE_MESSAGES == TRUE */
|
||||
|
||||
|
@ -153,40 +160,40 @@ static inline msg_t sbSendMessage(sb_class_t *sbcp, msg_t msg) {
|
|||
/**
|
||||
* @brief Adds a set of event flags directly to the specified sandbox.
|
||||
*
|
||||
* @param[in] sbcp pointer to the sandbox object
|
||||
* @param[in] sbp pointer to the sandbox object
|
||||
* @param[in] events the events set to be ORed
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline void sbEvtSignalI(sb_class_t *sbcp, eventmask_t events) {
|
||||
static inline void sbEvtSignalI(sb_class_t *sbp, eventmask_t events) {
|
||||
|
||||
chEvtSignalI(sbcp->tp, events);
|
||||
chEvtSignalI(sbp->tp, events);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a set of event flags directly to the specified sandbox.
|
||||
*
|
||||
* @param[in] sbcp pointer to the sandbox object
|
||||
* @param[in] sbp pointer to the sandbox object
|
||||
* @param[in] events the events set to be ORed
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline void sbEvtSignal(sb_class_t *sbcp, eventmask_t events) {
|
||||
static inline void sbEvtSignal(sb_class_t *sbp, eventmask_t events) {
|
||||
|
||||
chEvtSignal(sbcp->tp, events);
|
||||
chEvtSignal(sbp->tp, events);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the sandbox event source object.
|
||||
*
|
||||
* @param[in] sbcp pointer to the sandbox object
|
||||
* @param[in] sbp pointer to the sandbox object
|
||||
* @return The pointer to the event source object.
|
||||
*
|
||||
* @xclass
|
||||
*/
|
||||
static inline event_source_t *sbGetEventSourceX(sb_class_t *sbcp) {
|
||||
static inline event_source_t *sbGetEventSourceX(sb_class_t *sbp) {
|
||||
|
||||
return &sbcp->es;
|
||||
return &sbp->es;
|
||||
}
|
||||
#endif /* CH_CFG_USE_EVENTS == TRUE */
|
||||
|
||||
|
|
|
@ -65,22 +65,7 @@ static msg_t create_descriptor(sb_ioblock_t *iop,
|
|||
|
||||
return CH_RET_EMFILE;
|
||||
}
|
||||
|
||||
static bool is_valid_descriptor(int fd) {
|
||||
|
||||
return (fd >= 0) && (fd < SB_CFG_FD_NUM);
|
||||
}
|
||||
|
||||
static bool is_available_descriptor(sb_ioblock_t *iop, int fd) {
|
||||
|
||||
return (fd >= 0) && (fd < SB_CFG_FD_NUM) && (iop->vfs_nodes[fd] == NULL);
|
||||
}
|
||||
|
||||
static bool is_existing_descriptor(sb_ioblock_t *iop, int fd) {
|
||||
|
||||
return (fd >= 0) && (fd < SB_CFG_FD_NUM) && (iop->vfs_nodes[fd] != NULL);
|
||||
}
|
||||
#endif
|
||||
#endif /* SB_CFG_ENABLE_VFS == TRUE */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported functions. */
|
||||
|
@ -116,7 +101,7 @@ int sb_posix_open(const char *path, int flags) {
|
|||
int sb_posix_close(int fd) {
|
||||
sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
|
||||
|
||||
if (!is_existing_descriptor(&sbp->io, fd)) {
|
||||
if (!sb_is_existing_descriptor(&sbp->io, fd)) {
|
||||
return CH_RET_EBADF;
|
||||
}
|
||||
|
||||
|
@ -131,7 +116,7 @@ int sb_posix_dup(int fd) {
|
|||
vfs_node_c *np;
|
||||
msg_t ret;
|
||||
|
||||
if (!is_existing_descriptor(&sbp->io, fd)) {
|
||||
if (!sb_is_existing_descriptor(&sbp->io, fd)) {
|
||||
return CH_RET_EBADF;
|
||||
}
|
||||
|
||||
|
@ -152,11 +137,11 @@ int sb_posix_dup(int fd) {
|
|||
int sb_posix_dup2(int oldfd, int newfd) {
|
||||
sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
|
||||
|
||||
if (!is_existing_descriptor(&sbp->io, oldfd)) {
|
||||
if (!sb_is_existing_descriptor(&sbp->io, oldfd)) {
|
||||
return CH_RET_EBADF;
|
||||
}
|
||||
|
||||
if (!is_valid_descriptor(oldfd)) {
|
||||
if (!sb_is_valid_descriptor(oldfd)) {
|
||||
return CH_RET_EBADF;
|
||||
}
|
||||
|
||||
|
@ -182,7 +167,7 @@ int sb_posix_fstat(int fd, struct stat *statbuf) {
|
|||
return CH_RET_EFAULT;
|
||||
}
|
||||
|
||||
if (!is_existing_descriptor(&sbp->io, fd)) {
|
||||
if (!sb_is_existing_descriptor(&sbp->io, fd)) {
|
||||
return CH_RET_EBADF;
|
||||
}
|
||||
|
||||
|
@ -204,7 +189,7 @@ ssize_t sb_posix_read(int fd, void *buf, size_t count) {
|
|||
return CH_RET_EFAULT;
|
||||
}
|
||||
|
||||
if (!is_existing_descriptor(&sbp->io, fd)) {
|
||||
if (!sb_is_existing_descriptor(&sbp->io, fd)) {
|
||||
return CH_RET_EBADF;
|
||||
}
|
||||
|
||||
|
@ -222,7 +207,7 @@ ssize_t sb_posix_write(int fd, const void *buf, size_t count) {
|
|||
return CH_RET_EFAULT;
|
||||
}
|
||||
|
||||
if (!is_existing_descriptor(&sbp->io, fd)) {
|
||||
if (!sb_is_existing_descriptor(&sbp->io, fd)) {
|
||||
return CH_RET_EBADF;
|
||||
}
|
||||
|
||||
|
@ -240,7 +225,7 @@ off_t sb_posix_lseek(int fd, off_t offset, int whence) {
|
|||
return CH_RET_EINVAL;
|
||||
}
|
||||
|
||||
if (!is_existing_descriptor(&sbp->io, fd)) {
|
||||
if (!sb_is_existing_descriptor(&sbp->io, fd)) {
|
||||
return CH_RET_EBADF;
|
||||
}
|
||||
|
||||
|
@ -266,7 +251,7 @@ ssize_t sb_posix_getdents(int fd, void *buf, size_t count) {
|
|||
return (ssize_t)CH_RET_EFAULT;
|
||||
}
|
||||
|
||||
if (!is_existing_descriptor(&sbp->io, fd)) {
|
||||
if (!sb_is_existing_descriptor(&sbp->io, fd)) {
|
||||
return (ssize_t)CH_RET_EBADF;
|
||||
}
|
||||
|
||||
|
@ -307,13 +292,6 @@ ssize_t sb_posix_getdents(int fd, void *buf, size_t count) {
|
|||
return (ssize_t)ret;
|
||||
}
|
||||
|
||||
void sbPosixRegisterDescriptor(sb_class_t *sbp, int fd, vfs_node_c *np) {
|
||||
|
||||
chDbgAssert(is_available_descriptor(&sbp->io, fd), "invalid file descriptor");
|
||||
|
||||
sbp->io.vfs_nodes[fd] = np;
|
||||
}
|
||||
|
||||
#else /* Fallbacks for when there is no VFS.*/
|
||||
uint32_t sb_posix_open(const char *pathname, uint32_t flags) {
|
||||
|
||||
|
|
|
@ -68,9 +68,6 @@ extern "C" {
|
|||
ssize_t sb_posix_write(int fd, const void *buf, size_t count);
|
||||
off_t sb_posix_lseek(int fd, off_t offset, int whence);
|
||||
ssize_t sb_posix_getdents(int fd, void *buf, size_t count);
|
||||
#if SB_CFG_ENABLE_VFS == TRUE
|
||||
void sbPosixRegisterDescriptor(sb_class_t *sbp, int fd, vfs_node_c *np);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -79,6 +76,21 @@ extern "C" {
|
|||
/* Module inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
static inline bool sb_is_valid_descriptor(int fd) {
|
||||
|
||||
return (fd >= 0) && (fd < SB_CFG_FD_NUM);
|
||||
}
|
||||
|
||||
static inline bool sb_is_available_descriptor(sb_ioblock_t *iop, int fd) {
|
||||
|
||||
return (fd >= 0) && (fd < SB_CFG_FD_NUM) && (iop->vfs_nodes[fd] == NULL);
|
||||
}
|
||||
|
||||
static inline bool sb_is_existing_descriptor(sb_ioblock_t *iop, int fd) {
|
||||
|
||||
return (fd >= 0) && (fd < SB_CFG_FD_NUM) && (iop->vfs_nodes[fd] != NULL);
|
||||
}
|
||||
|
||||
#endif /* SBPOSIX_H */
|
||||
|
||||
/** @} */
|
||||
|
|
Loading…
Reference in New Issue