More memory checking code.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15356 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
277d9540a3
commit
077634725f
|
@ -80,9 +80,12 @@ extern const memory_area_t __ch_mem_executable_areas[];
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#if CH_CFG_USE_MEMCHECKS == TRUE
|
#if CH_CFG_USE_MEMCHECKS == TRUE
|
||||||
bool chMemIsStringWithinX(const memory_area_t *map,
|
size_t chMemIsStringWithinX(const memory_area_t *map,
|
||||||
const char *s,
|
const char *s,
|
||||||
size_t n);
|
size_t max);
|
||||||
|
size_t chMemIsPointersArrayWithinX(const memory_area_t *map,
|
||||||
|
const void *pp[],
|
||||||
|
size_t max);
|
||||||
bool chMemIsSpaceContainedX(const memory_area_t areas[],
|
bool chMemIsSpaceContainedX(const memory_area_t areas[],
|
||||||
const void *p,
|
const void *p,
|
||||||
size_t size);
|
size_t size);
|
||||||
|
|
|
@ -94,30 +94,67 @@ CC_WEAK const memory_area_t __ch_mem_executable_areas[] = {
|
||||||
*
|
*
|
||||||
* @param[in] map pointer to a @p memory_area_t structure
|
* @param[in] map pointer to a @p memory_area_t structure
|
||||||
* @param[in] s pointer to the string to be checked
|
* @param[in] s pointer to the string to be checked
|
||||||
* @param[in] n maximum expected size of the string
|
* @param[in] max maximum expected size of the string inclusive of the
|
||||||
* @return The test result.
|
* final zero
|
||||||
* @retval true if the string is entirely contained within one of the
|
* @return The string size inclusive of the final zero.
|
||||||
* specified areas.
|
* @retval 0 if the string check failed.
|
||||||
* @retval false if the string check failed.
|
|
||||||
*
|
*
|
||||||
* @xclass
|
* @xclass
|
||||||
*/
|
*/
|
||||||
bool chMemIsStringWithinX(const memory_area_t *map, const char *s, size_t n) {
|
size_t chMemIsStringWithinX(const memory_area_t *map,
|
||||||
|
const char *s,
|
||||||
|
size_t max) {
|
||||||
const char *base = (const char *)map->base;
|
const char *base = (const char *)map->base;
|
||||||
const char *end = (const char *)base + map->size - (size_t)1;
|
const char *end = (const char *)base + map->size - (size_t)1;
|
||||||
|
|
||||||
if (s >= base) {
|
if (s >= base) {
|
||||||
while ((s <= end) && (n > 0U)) {
|
size_t n;
|
||||||
if (*s == '\0') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
s++;
|
n = (size_t)0;
|
||||||
n--;
|
while ((s <= end) && (n < max)) {
|
||||||
|
n++;
|
||||||
|
if (*s++ == '\0') {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return (size_t)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pointers array check.
|
||||||
|
* @details Checks if specified pointers array is entirely contained in the
|
||||||
|
* specified memory area.
|
||||||
|
*
|
||||||
|
* @param[in] map pointer to a @p memory_area_t structure
|
||||||
|
* @param[in] pp zero-terminated pointers array to be checked
|
||||||
|
* @param[in] max maximum expected size of the pointers array inclusive
|
||||||
|
* of the final zero
|
||||||
|
* @return The pointers array size inclusive of the final zero.
|
||||||
|
* @retval 0 if the pointers array check failed.
|
||||||
|
*
|
||||||
|
* @xclass
|
||||||
|
*/
|
||||||
|
size_t chMemIsPointersArrayWithinX(const memory_area_t *map,
|
||||||
|
const void *pp[],
|
||||||
|
size_t max) {
|
||||||
|
const void **base = (const void **)(void *)map->base;
|
||||||
|
const void **end = (const void **)(void *)(map->base + map->size - sizeof (void *));
|
||||||
|
|
||||||
|
if (pp >= base) {
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
n = (size_t)0;
|
||||||
|
while ((pp <= end) && (n < max)) {
|
||||||
|
n += sizeof (void *);
|
||||||
|
if (*pp++ == NULL) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (size_t)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -61,7 +61,7 @@ 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];
|
const sb_memory_region_t *rp = &sbcp->config->regions[0];
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (chMemIsSpaceWithinX(&rp->area, start, size)) {
|
if (rp->used && chMemIsSpaceWithinX(&rp->area, start, size)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
rp++;
|
rp++;
|
||||||
|
@ -74,7 +74,7 @@ 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];
|
const sb_memory_region_t *rp = &sbcp->config->regions[0];
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (chMemIsSpaceWithinX(&rp->area, start, size)) {
|
if (rp->used && chMemIsSpaceWithinX(&rp->area, start, size)) {
|
||||||
return rp->writeable;
|
return rp->writeable;
|
||||||
}
|
}
|
||||||
rp++;
|
rp++;
|
||||||
|
@ -83,17 +83,57 @@ bool sb_is_valid_write_range(sb_class_t *sbcp, void *start, size_t size) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sb_is_valid_string_range(sb_class_t *sbcp, const char *s, size_t n) {
|
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];
|
const sb_memory_region_t *rp = &sbcp->config->regions[0];
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (chMemIsStringWithinX(&rp->area, s, n)) {
|
if (rp->used) {
|
||||||
return true;
|
size_t n = chMemIsStringWithinX(&rp->area, s, max);
|
||||||
|
if (n > (size_t)0) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rp++;
|
rp++;
|
||||||
} while (rp < &sbcp->config->regions[SB_CFG_NUM_REGIONS]);
|
} while (rp < &sbcp->config->regions[SB_CFG_NUM_REGIONS]);
|
||||||
|
|
||||||
return false;
|
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];
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (rp->used) {
|
||||||
|
size_t an = chMemIsPointersArrayWithinX(&rp->area, pp, max);
|
||||||
|
if (an > (size_t)0) {
|
||||||
|
return an;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rp++;
|
||||||
|
} while (rp < &sbcp->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) {
|
||||||
|
const char *s;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
n = sb_check_pointers_array(sbcp, (const void **)pp, max);
|
||||||
|
if (n > (size_t)0) {
|
||||||
|
while ((s = *pp++) != NULL) {
|
||||||
|
size_t sn;
|
||||||
|
|
||||||
|
sn = sb_check_string(sbcp, s, max - n);
|
||||||
|
if (sn == (size_t)0) {
|
||||||
|
return (size_t)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
n += sn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -94,7 +94,9 @@ extern "C" {
|
||||||
void port_syscall(struct port_extctx *ctxp, uint32_t n);
|
void port_syscall(struct port_extctx *ctxp, uint32_t n);
|
||||||
bool sb_is_valid_read_range(sb_class_t *sbcp, const void *start, size_t size);
|
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);
|
bool sb_is_valid_write_range(sb_class_t *sbcp, void *start, size_t size);
|
||||||
bool sb_is_valid_string_range(sb_class_t *sbcp, const char *s, size_t n);
|
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);
|
void sbObjectInit(sb_class_t *sbcp, const sb_config_t *config);
|
||||||
thread_t *sbStartThread(sb_class_t *sbcp, const char *name,
|
thread_t *sbStartThread(sb_class_t *sbcp, const char *name,
|
||||||
void *wsp, size_t size, tprio_t prio,
|
void *wsp, size_t size, tprio_t prio,
|
||||||
|
|
|
@ -92,7 +92,7 @@ int sb_posix_open(const char *path, int flags) {
|
||||||
vfs_node_c *np = NULL;
|
vfs_node_c *np = NULL;
|
||||||
msg_t ret;
|
msg_t ret;
|
||||||
|
|
||||||
if (!sb_is_valid_string_range(sbp, (void *)path, VFS_CFG_PATHLEN_MAX)) {
|
if (sb_check_string(sbp, (void *)path, VFS_CFG_PATHLEN_MAX + 1) == (size_t)0) {
|
||||||
return CH_RET_EFAULT;
|
return CH_RET_EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue