2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 23:25:38 +00:00

ISC_MEM_FILL was corrupting memory when the block being allocated or freed

was bigger than the memory context's max size.

Force alignment to 8 bytes, since some otherwise 32-bit platforms have a 64
bit "long long".
This commit is contained in:
Bob Halley
1999-10-27 20:55:21 +00:00
parent 12bf2c63ea
commit b622f2b07b

View File

@@ -54,6 +54,17 @@
#define ISC_MEMPOOL_NAMES 1 #define ISC_MEMPOOL_NAMES 1
#endif #endif
/*
* Constants.
*/
#define DEF_MAX_SIZE 1100
#define DEF_MEM_TARGET 4096
#define ALIGNMENT_SIZE 8
#define NUM_BASIC_BLOCKS 64 /* must be > 1 */
#define TABLE_INCREMENT 1024
/* /*
* Types. * Types.
*/ */
@@ -63,10 +74,13 @@ typedef struct {
} element; } element;
typedef struct { typedef struct {
size_t size;
/* /*
* This structure must be ALIGNMENT_SIZE bytes. * This structure must be ALIGNMENT_SIZE bytes.
*/ */
union {
size_t size;
char bytes[ALIGNMENT_SIZE];
} u;
} size_info; } size_info;
struct stats { struct stats {
@@ -127,21 +141,17 @@ struct isc_mempool {
#endif #endif
}; };
/* Forward. */ /*
* Forward.
*/
static inline size_t quantize(size_t); static inline size_t quantize(size_t);
static inline void mem_putunlocked(isc_mem_t *, void *, size_t); static inline void mem_putunlocked(isc_mem_t *, void *, size_t);
static inline void * mem_getunlocked(isc_mem_t *, size_t); static inline void * mem_getunlocked(isc_mem_t *, size_t);
/* Constants. */ /*
* Private Inline-able.
#define DEF_MAX_SIZE 1100 */
#define DEF_MEM_TARGET 4096
#define ALIGNMENT_SIZE sizeof (void *)
#define NUM_BASIC_BLOCKS 64 /* must be > 1 */
#define TABLE_INCREMENT 1024
/* Private Inline-able. */
static inline size_t static inline size_t
quantize(size_t size) { quantize(size_t size) {
@@ -157,7 +167,9 @@ quantize(size_t size) {
return (temp - temp % ALIGNMENT_SIZE); return (temp - temp % ALIGNMENT_SIZE);
} }
/* Private. */ /*
* Private.
*/
static void * static void *
default_memalloc(void *arg, size_t size) { default_memalloc(void *arg, size_t size) {
@@ -171,7 +183,9 @@ default_memfree(void *arg, void *ptr) {
free(ptr); free(ptr);
} }
/* Public. */ /*
* Public.
*/
isc_result_t isc_result_t
isc_mem_createx(size_t init_max_size, size_t target_size, isc_mem_createx(size_t init_max_size, size_t target_size,
@@ -391,6 +405,12 @@ mem_getunlocked(isc_mem_t *ctx, size_t size)
ctx->total += size; ctx->total += size;
ctx->stats[ctx->max_size].gets++; ctx->stats[ctx->max_size].gets++;
ctx->stats[ctx->max_size].totalgets++; ctx->stats[ctx->max_size].totalgets++;
/*
* If we don't set new_size to size, then the
* ISC_MEM_FILL code might write over bytes we
* don't own.
*/
new_size = size;
} }
goto done; goto done;
} }
@@ -472,12 +492,11 @@ mem_putunlocked(isc_mem_t *ctx, void *mem, size_t size)
{ {
size_t new_size = quantize(size); size_t new_size = quantize(size);
#if ISC_MEM_FILL
memset(mem, 0xde, new_size); /* Mnemonic for "dead". */
#endif
if (size == ctx->max_size || new_size >= ctx->max_size) { if (size == ctx->max_size || new_size >= ctx->max_size) {
/* memput() called on something beyond our upper limit */ /* memput() called on something beyond our upper limit */
#if ISC_MEM_FILL
memset(mem, 0xde, size); /* Mnemonic for "dead". */
#endif
(ctx->memfree)(ctx->arg, mem); (ctx->memfree)(ctx->arg, mem);
INSIST(ctx->stats[ctx->max_size].gets != 0); INSIST(ctx->stats[ctx->max_size].gets != 0);
ctx->stats[ctx->max_size].gets--; ctx->stats[ctx->max_size].gets--;
@@ -486,6 +505,10 @@ mem_putunlocked(isc_mem_t *ctx, void *mem, size_t size)
return; return;
} }
#if ISC_MEM_FILL
memset(mem, 0xde, new_size); /* Mnemonic for "dead". */
#endif
/* The free list uses the "rounded-up" size "new_size": */ /* The free list uses the "rounded-up" size "new_size": */
((element *)mem)->next = ctx->freelists[new_size]; ((element *)mem)->next = ctx->freelists[new_size];
ctx->freelists[new_size] = (element *)mem; ctx->freelists[new_size] = (element *)mem;
@@ -603,7 +626,7 @@ isc_mem_allocate(isc_mem_t *ctx, size_t size) {
si = isc_mem_get(ctx, size); si = isc_mem_get(ctx, size);
if (si == NULL) if (si == NULL)
return (NULL); return (NULL);
si->size = size; si->u.size = size;
return (&si[1]); return (&si[1]);
} }
@@ -612,7 +635,7 @@ isc_mem_free(isc_mem_t *ctx, void *ptr) {
size_info *si; size_info *si;
si = &(((size_info *)ptr)[-1]); si = &(((size_info *)ptr)[-1]);
isc_mem_put(ctx, si, si->size); isc_mem_put(ctx, si, si->u.size);
} }
/* /*