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:
Giovanni Di Sirio 2022-01-13 20:02:03 +00:00
parent 277d9540a3
commit 077634725f
5 changed files with 106 additions and 24 deletions

View File

@ -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);

View File

@ -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;
}
/**

View File

@ -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;
}
/**

View File

@ -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,

View File

@ -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;
}