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" {
|
||||
#endif
|
||||
#if CH_CFG_USE_MEMCHECKS == TRUE
|
||||
bool chMemIsStringWithinX(const memory_area_t *map,
|
||||
size_t chMemIsStringWithinX(const memory_area_t *map,
|
||||
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[],
|
||||
const void *p,
|
||||
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] s pointer to the string to be checked
|
||||
* @param[in] n maximum expected size of the string
|
||||
* @return The test result.
|
||||
* @retval true if the string is entirely contained within one of the
|
||||
* specified areas.
|
||||
* @retval false if the string check failed.
|
||||
* @param[in] max maximum expected size of the string inclusive of the
|
||||
* final zero
|
||||
* @return The string size inclusive of the final zero.
|
||||
* @retval 0 if the string check failed.
|
||||
*
|
||||
* @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 *end = (const char *)base + map->size - (size_t)1;
|
||||
|
||||
if (s >= base) {
|
||||
while ((s <= end) && (n > 0U)) {
|
||||
if (*s == '\0') {
|
||||
return true;
|
||||
}
|
||||
size_t n;
|
||||
|
||||
s++;
|
||||
n--;
|
||||
n = (size_t)0;
|
||||
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];
|
||||
|
||||
do {
|
||||
if (chMemIsSpaceWithinX(&rp->area, start, size)) {
|
||||
if (rp->used && chMemIsSpaceWithinX(&rp->area, start, size)) {
|
||||
return true;
|
||||
}
|
||||
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];
|
||||
|
||||
do {
|
||||
if (chMemIsSpaceWithinX(&rp->area, start, size)) {
|
||||
if (rp->used && chMemIsSpaceWithinX(&rp->area, start, size)) {
|
||||
return rp->writeable;
|
||||
}
|
||||
rp++;
|
||||
|
@ -83,17 +83,57 @@ bool sb_is_valid_write_range(sb_class_t *sbcp, void *start, size_t size) {
|
|||
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];
|
||||
|
||||
do {
|
||||
if (chMemIsStringWithinX(&rp->area, s, n)) {
|
||||
return true;
|
||||
if (rp->used) {
|
||||
size_t n = chMemIsStringWithinX(&rp->area, s, max);
|
||||
if (n > (size_t)0) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
rp++;
|
||||
} 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);
|
||||
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_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);
|
||||
thread_t *sbStartThread(sb_class_t *sbcp, const char *name,
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue