From e53303032cbd3a5b7ddd04025f532c14ff5f5533 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Fri, 10 Jan 2003 09:38:01 +0000 Subject: [PATCH] Buffer overrun fixes git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@280 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/findlib/attribs.c | 4 +- bacula/src/lib/mem_pool.c | 119 ++++++++++++++++++++++++----------- bacula/src/lib/mem_pool.h | 26 +++++--- 3 files changed, 103 insertions(+), 46 deletions(-) diff --git a/bacula/src/findlib/attribs.c b/bacula/src/findlib/attribs.c index 57e4cd3fee..8ef3d7b359 100755 --- a/bacula/src/findlib/attribs.c +++ b/bacula/src/findlib/attribs.c @@ -402,8 +402,8 @@ extern "C" void cygwin_conv_to_win32_path(const char *path, char *win32_path); void unix_name_to_win32(POOLMEM **win32_name, char *name) { - /* One extra byte should suffice, but we take 10 */ - *win32_name = check_pool_memory_size(*win32_name, strlen(name)+10); + /* One extra byte should suffice, but we double it */ + *win32_name = check_pool_memory_size(*win32_name, 2*strlen(name)+1); cygwin_conv_to_win32_path(name, *win32_name); } diff --git a/bacula/src/lib/mem_pool.c b/bacula/src/lib/mem_pool.c index c5443ac354..584dcddf77 100644 --- a/bacula/src/lib/mem_pool.c +++ b/bacula/src/lib/mem_pool.c @@ -129,6 +129,54 @@ POOLMEM *sm_get_memory(char *fname, int lineno, size_t size) return (POOLMEM *)(((char *)buf)+HEAD_SIZE); } + +/* Return the size of a memory buffer */ +size_t sm_sizeof_pool_memory(char *fname, int lineno, POOLMEM *obuf) +{ + char *cp = (char *)obuf; + + sm_check(fname, lineno, False); + ASSERT(obuf); + cp -= HEAD_SIZE; + return ((struct abufhead *)cp)->ablen; +} + +/* Realloc pool memory buffer */ +POOLMEM *sm_realloc_pool_memory(char *fname, int lineno, POOLMEM *obuf, size_t size) +{ + char *cp = (char *)obuf; + void *buf; + int pool; + + sm_check(fname, lineno, False); + ASSERT(obuf); + P(mutex); + cp -= HEAD_SIZE; + buf = realloc(cp, size+HEAD_SIZE); + if (buf == NULL) { + V(mutex); + Emsg1(M_ABORT, 0, "Out of memory requesting %d bytes\n", size); + } + ((struct abufhead *)buf)->ablen = size; + pool = ((struct abufhead *)buf)->pool; + if (size > pool_ctl[pool].max_size) { + pool_ctl[pool].max_size = size; + } + V(mutex); + sm_check(fname, lineno, False); + return (POOLMEM *)(((char *)buf)+HEAD_SIZE); +} + +POOLMEM *sm_check_pool_memory_size(char *fname, int lineno, POOLMEM *obuf, size_t size) +{ + sm_check(fname, lineno, False); + ASSERT(obuf); + if (size <= sizeof_pool_memory(obuf)) { + return obuf; + } + return realloc_pool_memory(obuf, size); +} + #else POOLMEM *get_pool_memory(int pool) @@ -176,38 +224,6 @@ POOLMEM *get_memory(size_t size) } return (POOLMEM *)(((char *)buf)+HEAD_SIZE); } -#endif /* SMARTALLOC */ - - - -/* Free a memory buffer */ -void free_pool_memory(POOLMEM *obuf) -{ - struct abufhead *buf; - int pool; - - sm_check(__FILE__, __LINE__, False); - ASSERT(obuf); - P(mutex); - buf = (struct abufhead *)((char *)obuf - HEAD_SIZE); - pool = buf->pool; - pool_ctl[pool].in_use--; - if (pool == 0) { - free((char *)buf); /* free nonpooled memory */ - } else { /* otherwise link it to the free pool chain */ -#ifdef DEBUG - struct abufhead *next; - /* Don't let him free the same buffer twice */ - for (next=pool_ctl[pool].free_buf; next; next=next->next) { - ASSERT(next != buf); /* attempt to free twice */ - } -#endif - buf->next = pool_ctl[pool].free_buf; - pool_ctl[pool].free_buf = buf; - } - Dmsg2(150, "free_pool_memory %x pool=%d\n", buf, pool); - V(mutex); -} /* Return the size of a memory buffer */ @@ -215,7 +231,6 @@ size_t sizeof_pool_memory(POOLMEM *obuf) { char *cp = (char *)obuf; - sm_check(__FILE__, __LINE__, False); ASSERT(obuf); cp -= HEAD_SIZE; return ((struct abufhead *)cp)->ablen; @@ -228,7 +243,6 @@ POOLMEM *realloc_pool_memory(POOLMEM *obuf, size_t size) void *buf; int pool; - sm_check(__FILE__, __LINE__, False); ASSERT(obuf); P(mutex); cp -= HEAD_SIZE; @@ -243,13 +257,11 @@ POOLMEM *realloc_pool_memory(POOLMEM *obuf, size_t size) pool_ctl[pool].max_size = size; } V(mutex); - sm_check(__FILE__, __LINE__, False); return (POOLMEM *)(((char *)buf)+HEAD_SIZE); } POOLMEM *check_pool_memory_size(POOLMEM *obuf, size_t size) { - sm_check(__FILE__, __LINE__, False); ASSERT(obuf); if (size <= sizeof_pool_memory(obuf)) { return obuf; @@ -257,6 +269,41 @@ POOLMEM *check_pool_memory_size(POOLMEM *obuf, size_t size) return realloc_pool_memory(obuf, size); } +#endif /* SMARTALLOC */ + + + +/* Free a memory buffer */ +void free_pool_memory(POOLMEM *obuf) +{ + struct abufhead *buf; + int pool; + + sm_check(__FILE__, __LINE__, False); + ASSERT(obuf); + P(mutex); + buf = (struct abufhead *)((char *)obuf - HEAD_SIZE); + pool = buf->pool; + pool_ctl[pool].in_use--; + if (pool == 0) { + free((char *)buf); /* free nonpooled memory */ + } else { /* otherwise link it to the free pool chain */ +#ifdef DEBUG + struct abufhead *next; + /* Don't let him free the same buffer twice */ + for (next=pool_ctl[pool].free_buf; next; next=next->next) { + ASSERT(next != buf); /* attempt to free twice */ + } +#endif + buf->next = pool_ctl[pool].free_buf; + pool_ctl[pool].free_buf = buf; + } + Dmsg2(150, "free_pool_memory %x pool=%d\n", buf, pool); + V(mutex); +} + + + /* Release all pooled memory */ void close_memory_pool() { diff --git a/bacula/src/lib/mem_pool.h b/bacula/src/lib/mem_pool.h index 5378ea7411..c1bc88a2d8 100644 --- a/bacula/src/lib/mem_pool.h +++ b/bacula/src/lib/mem_pool.h @@ -29,26 +29,36 @@ #define get_pool_memory(pool) sm_get_pool_memory(__FILE__, __LINE__, pool) extern POOLMEM *sm_get_pool_memory(char *file, int line, int pool); + #define get_memory(size) sm_get_memory(__FILE__, __LINE__, size) extern POOLMEM *sm_get_memory(char *fname, int line, size_t size); +#define sizeof_pool_memory(buf) sm_sizeof_pool_memory(__FILE__, __LINE__, buf) +extern size_t sm_sizeof_pool_memory(char *fname, int line, POOLMEM *buf); + +#define realloc_pool_memory(buf,size) sm_realloc_pool_memory(__FILE__, __LINE__, buf, size) +extern POOLMEM *sm_realloc_pool_memory(char *fname, int line, POOLMEM *buf, size_t size); + +#define check_pool_memory_size(buf,size) sm_check_pool_memory_size(__FILE__, __LINE__, buf, size) +extern POOLMEM *sm_check_pool_memory_size(char *fname, int line, POOLMEM *buf, size_t size); + #else extern POOLMEM *get_pool_memory(int pool); extern POOLMEM *get_memory(size_t size); +extern size_t sizeof_pool_memory(POOLMEM *buf); +extern POOLMEM *realloc_pool_memory(POOLMEM *buf, size_t size); +extern POOLMEM *check_pool_memory_size(POOLMEM *buf, size_t size); #endif #define free_memory(x) free_pool_memory(x) extern void free_pool_memory(POOLMEM *buf); -extern size_t sizeof_pool_memory(POOLMEM *buf); -extern POOLMEM *realloc_pool_memory(POOLMEM *buf, size_t size); -extern POOLMEM *check_pool_memory_size(POOLMEM *buf, size_t size); extern void close_memory_pool(); extern void print_memory_pool_stats(); -#define PM_NOPOOL 0 /* nonpooled memory */ -#define PM_FNAME 1 /* file name buffer */ -#define PM_MESSAGE 2 /* daemon message */ -#define PM_EMSG 3 /* error message */ -#define PM_MAX PM_EMSG /* Number of types */ +#define PM_NOPOOL 0 /* nonpooled memory */ +#define PM_FNAME 1 /* file name buffer */ +#define PM_MESSAGE 2 /* daemon message */ +#define PM_EMSG 3 /* error message */ +#define PM_MAX PM_EMSG /* Number of types */ -- 2.39.5