From: Gerald Carter Date: Sat, 8 Apr 2006 17:25:31 +0000 (+0000) Subject: r15003: patch based on code from Arkady Glabek to ensure that... X-Git-Tag: release-3-0-23~54^2~51 X-Git-Url: http://git.samba.org/samba.git/?p=tprouty%2Fsamba.git;a=commitdiff_plain;h=391c84d8400aad583488720adfddfa346bd5b4f0 r15003: patch based on code from Arkady Glabek to ensure that global memory is freed when unloading pam_winbind.so (needs more testing on non-linux platforms) --- diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c index ae04fd9ffb..097d746a63 100644 --- a/source/lib/charcnv.c +++ b/source/lib/charcnv.c @@ -101,6 +101,23 @@ void lazy_initialize_conv(void) } } +/** + * Destroy global objects allocated by init_iconv() + **/ +void gfree_charcnv(void) +{ + int c1, c2; + + for (c1=0;c1next; + DLIST_REMOVE(dispatch_fns, dfn); + SAFE_FREE(dfn); + dfn = next; + } +} + /**************************************************************************** Notifications come in as signals. ****************************************************************************/ diff --git a/source/lib/talloc.c b/source/lib/talloc.c index ba189199d7..c111615506 100644 --- a/source/lib/talloc.c +++ b/source/lib/talloc.c @@ -882,6 +882,16 @@ static void talloc_report_null_full(void) } } +/* + free allocated global memory +*/ + +void talloc_nc_free(void) +{ + if ( null_context ) + talloc_free( (void*)null_context ); +} + /* enable tracking of the NULL context */ diff --git a/source/lib/util.c b/source/lib/util.c index 0fbe4a13d3..bfc5eb2a8d 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -179,6 +179,31 @@ static BOOL set_my_netbios_names(const char *name, int i) return True; } +/*********************************************************************** + Free memory allocated to global objects +***********************************************************************/ + +void gfree_names(void) +{ + SAFE_FREE( smb_myname ); + SAFE_FREE( smb_myworkgroup ); + SAFE_FREE( smb_scope ); + free_netbios_names_array(); +} + +void gfree_all( void ) +{ + gfree_names(); + gfree_loadparm(); + gfree_case_tables(); + gfree_debugsyms(); + gfree_charcnv(); + gfree_messsges(); + + /* release the talloc null_context memory last */ + talloc_nc_free(); +} + const char *my_netbios_names(int i) { return smb_my_netbios_names[i]; diff --git a/source/lib/util_file.c b/source/lib/util_file.c index 06008886c0..fff564aeb0 100644 --- a/source/lib/util_file.c +++ b/source/lib/util_file.c @@ -440,6 +440,26 @@ char *file_load(const char *fname, size_t *size, size_t maxsize) return p; } +/******************************************************************* + unmap or free memory +*******************************************************************/ + +BOOL unmap_file(void* start, size_t size) +{ +#ifdef HAVE_MMAP + if ( munmap( start, size ) != 0 ) { + DEBUG( 1, ("map_file: Failed to unmap address %X " + "of size %d - %s\n", + start, size, strerror(errno) )); + return False; + } + return True; +#else + SAFE_FREE( start ); + return True; +#endif +} + /******************************************************************* mmap (if possible) or read a file. ********************************************************************/ diff --git a/source/lib/util_str.c b/source/lib/util_str.c index 446a4a00a1..439cbea6d9 100644 --- a/source/lib/util_str.c +++ b/source/lib/util_str.c @@ -853,7 +853,7 @@ BOOL in_list(const char *s, const char *list, BOOL casesensitive) } /* this is used to prevent lots of mallocs of size 1 */ -static char *null_string = NULL; +static const char *null_string = ""; /** Set a string value, allocing the space for the string @@ -862,20 +862,14 @@ static char *null_string = NULL; static BOOL string_init(char **dest,const char *src) { size_t l; + if (!src) src = ""; l = strlen(src); if (l == 0) { - if (!null_string) { - if((null_string = (char *)SMB_MALLOC(1)) == NULL) { - DEBUG(0,("string_init: malloc fail for null_string.\n")); - return False; - } - *null_string = 0; - } - *dest = null_string; + *dest = CONST_DISCARD(char*, null_string); } else { (*dest) = SMB_STRDUP(src); if ((*dest) == NULL) { diff --git a/source/lib/util_unistr.c b/source/lib/util_unistr.c index 9713c0ccb7..eef484148d 100644 --- a/source/lib/util_unistr.c +++ b/source/lib/util_unistr.c @@ -31,6 +31,9 @@ static smb_ucs2_t *upcase_table; static smb_ucs2_t *lowcase_table; static uint8 *valid_table; +static BOOL upcase_table_use_unmap; +static BOOL lowcase_table_use_unmap; +static BOOL valid_table_use_unmap; /** * This table says which Unicode characters are valid dos @@ -40,6 +43,32 @@ static uint8 *valid_table; **/ static uint8 doschar_table[8192]; /* 65536 characters / 8 bits/byte */ +/** + * Destroy global objects allocated by load_case_tables() + **/ +void gfree_case_tables(void) +{ + if ( upcase_table ) { + if ( upcase_table_use_unmap ) + unmap_file(upcase_table, 0x20000); + else + SAFE_FREE(upcase_table); + } + + if ( lowcase_table ) { + if ( lowcase_table_use_unmap ) + unmap_file(lowcase_table, 0x20000); + else + SAFE_FREE(lowcase_table); + } + + if ( valid_table ) { + if ( valid_table_use_unmap ) + unmap_file(valid_table, 0x10000); + else + SAFE_FREE(valid_table); + } +} /** * Load or generate the case handling tables. @@ -60,7 +89,10 @@ void load_case_tables(void) initialised = 1; upcase_table = map_file(lib_path("upcase.dat"), 0x20000); + upcase_table_use_unmap = ( upcase_table != NULL ); + lowcase_table = map_file(lib_path("lowcase.dat"), 0x20000); + lowcase_table_use_unmap = ( lowcase_table != NULL ); #ifdef HAVE_SETLOCALE /* Get the name of the current locale. */ @@ -196,6 +228,7 @@ void init_valid_table(void) if (valid_file) { valid_table = valid_file; mapped_file = 1; + valid_table_use_unmap = True; return; } @@ -203,7 +236,11 @@ void init_valid_table(void) * It might need to be regenerated if the code page changed. * We know that we're not using a mapped file, so we can * free() the old one. */ - if (valid_table) free(valid_table); + if (valid_table) + SAFE_FREE(valid_table); + + /* use free rather than unmap */ + valid_table_use_unmap = False; DEBUG(2,("creating default valid table\n")); valid_table = SMB_MALLOC(0x10000); diff --git a/source/nsswitch/pam_winbind.c b/source/nsswitch/pam_winbind.c index d78d65287e..2db10b69a8 100644 --- a/source/nsswitch/pam_winbind.c +++ b/source/nsswitch/pam_winbind.c @@ -17,6 +17,16 @@ #define MAX_PASSWD_TRIES 3 +/******************************************************************* + Need this destructor to free global memory when the shared library + is unloaded +*******************************************************************/ + +void __attribute__ ((destructor)) _fini_pam_winbind(void) +{ + gfree_all(); +} + /* some syslogging */ static void _pam_log(int err, const char *format, ...) { diff --git a/source/param/loadparm.c b/source/param/loadparm.c index b7d6546fd9..e0c6c0686f 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -4865,6 +4865,56 @@ int load_usershare_shares(void) return lp_numservices(); } +/******************************************************** + Destroy global resources allocated in this file +********************************************************/ + +void gfree_loadparm(void) +{ + struct file_lists *f; + struct file_lists *next; + int i; + + lp_TALLOC_FREE(); + + /* Free the file lists */ + + f = file_lists; + while( f ) { + next = f->next; + SAFE_FREE( f->name ); + SAFE_FREE( f->subfname ); + SAFE_FREE( f ); + f = next; + } + + /* Free resources allocated to services */ + + for ( i = 0; i < iNumServices; i++ ) { + if ( VALID(i) ) { + free_service_byindex(i); + } + } + + SAFE_FREE( ServicePtrs ); + iNumServices = 0; + + /* Now release all resources allocated to global + parameters and the default service */ + + for (i = 0; parm_table[i].label; i++) + { + if ( parm_table[i].type == P_STRING + || parm_table[i].type == P_USTRING ) + { + string_free( (char**)parm_table[i].ptr ); + } + else if (parm_table[i].type == P_LIST) { + str_list_free( (char***)parm_table[i].ptr ); + } + } +} + /*************************************************************************** Load the services array from the services file. Return True on success, False on failure.