diff options
-rw-r--r-- | source/configure.in | 1 | ||||
-rw-r--r-- | source/include/smb_macros.h | 1 | ||||
-rw-r--r-- | source/lib/system.c | 21 | ||||
-rw-r--r-- | source/lib/util.c | 28 | ||||
-rw-r--r-- | source/nsswitch/winbindd_cred_cache.c | 30 | ||||
-rw-r--r-- | source/nsswitch/winbindd_nss.h | 2 |
6 files changed, 61 insertions, 22 deletions
diff --git a/source/configure.in b/source/configure.in index f84cd68a628..93d18284bc3 100644 --- a/source/configure.in +++ b/source/configure.in @@ -1240,6 +1240,7 @@ AC_CHECK_FUNCS(syslog vsyslog timegm) AC_CHECK_FUNCS(setlocale nl_langinfo) AC_CHECK_FUNCS(nanosleep) AC_CHECK_FUNCS(mlock munlock mlockall munlockall) +AC_CHECK_FUNCS(memalign posix_memalign) AC_CHECK_HEADERS(sys/mman.h) # setbuffer, shmget, shm_open are needed for smbtorture AC_CHECK_FUNCS(setbuffer shmget shm_open) diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h index 4b4351347fc..4ca227c21ee 100644 --- a/source/include/smb_macros.h +++ b/source/include/smb_macros.h @@ -276,6 +276,7 @@ copy an IP address from one buffer to another *****************************************************************************/ #define SMB_MALLOC_ARRAY(type,count) (type *)malloc_array(sizeof(type),(count)) +#define SMB_MEMALIGN_ARRAY(type,align,count) (type *)memalign_array(sizeof(type),align,(count)) #define SMB_REALLOC(p,s) Realloc((p),(s),True) /* Always frees p on error or s == 0 */ #define SMB_REALLOC_KEEP_OLD_ON_ERROR(p,s) Realloc((p),(s),False) /* Never frees p on error or s == 0 */ #define SMB_REALLOC_ARRAY(p,type,count) (type *)realloc_array((p),sizeof(type),(count),True) /* Always frees p on error or s == 0 */ diff --git a/source/lib/system.c b/source/lib/system.c index 9ee3f7cc26a..5e70fb8ac5e 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -44,6 +44,27 @@ /******************************************************************* + A wrapper for memalign +********************************************************************/ + +void* sys_memalign( size_t align, size_t size ) +{ +#if defined(HAVE_MEMALIGN) + return memalign( align, size ); +#elif defined(HAVE_POSIX_MEMALIGN) + char *p = NULL; + int ret = posix_memalign( &p, align, size ); + if ( ret == 0 ) + return p; + + return NULL; +#else + DEBUG(0,("memalign functionalaity not available on this platform!\n")); + return NULL; +#endif +} + +/******************************************************************* A wrapper for usleep in case we don't have one. ********************************************************************/ diff --git a/source/lib/util.c b/source/lib/util.c index 7d41a14292c..5f9eb4fc450 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -913,6 +913,17 @@ void *malloc_(size_t size) } /**************************************************************************** + Internal malloc wrapper. Externally visible. +****************************************************************************/ + +void *memalign_(size_t align, size_t size) +{ +#undef memalign + return memalign(align, size); +#define memalign(align, s) __ERROR_DONT_USE_MEMALIGN_DIRECTLY +} + +/**************************************************************************** Internal calloc wrapper. Not externally visible. ****************************************************************************/ @@ -954,6 +965,23 @@ void *malloc_array(size_t el_size, unsigned int count) } /**************************************************************************** + Type-safe memalign +****************************************************************************/ + +void *memalign_array(size_t el_size, size_t align, unsigned int count) +{ + if (count >= MAX_ALLOC_SIZE/el_size) { + return NULL; + } + +#if defined(PARANOID_MALLOC_CHECKER) + return memalign_(align, el_size*count); +#else + return sys_memalign(align, el_size*count); +#endif +} + +/**************************************************************************** Type-safe calloc. ****************************************************************************/ diff --git a/source/nsswitch/winbindd_cred_cache.c b/source/nsswitch/winbindd_cred_cache.c index 8dc8fab4ac1..bd2798d68bc 100644 --- a/source/nsswitch/winbindd_cred_cache.c +++ b/source/nsswitch/winbindd_cred_cache.c @@ -482,29 +482,21 @@ static NTSTATUS store_memory_creds(struct WINBINDD_MEMORY_CREDS *memcredp, const memcredp->len += strlen(pass)+1; } - /* On non-linux platforms, mlock()'d memory must be aligned on - a page boundary so allocate a bit more so we can offset - enough */ - - memcredp->len += psize; - - memcredp->buffer = (unsigned char*)TALLOC_ZERO(memcredp, memcredp->len); - - if (!memcredp->buffer) { + /* On non-linux platforms, mlock()'d memory must be aligned */ + + memcredp->nt_hash = SMB_MEMALIGN_ARRAY(unsigned char*, psize, + memcredp->len); + if (!memcredp->nt_hash) { return NT_STATUS_NO_MEMORY; } - - - /* point the nt_hash at the page boundary in the buffer */ + memset( memcredp->nt_hash, 0x0, memcredp->len ); - memcredp->nt_hash = memcredp->buffer + - (psize - ((uint32)memcredp->buffer % psize)); memcredp->lm_hash = memcredp->nt_hash + NT_HASH_LEN; #ifdef DEBUG_PASSWORD DEBUG(10,("mlocking memory: %p\n", memcredp->nt_hash)); #endif - if ((mlock(memcredp->nt_hash, memcredp->len-psize)) == -1) { + if ((mlock(memcredp->nt_hash, memcredp->len)) == -1) { DEBUG(0,("failed to mlock memory: %s (%d)\n", strerror(errno), errno)); return map_nt_error_from_unix(errno); @@ -536,15 +528,13 @@ static NTSTATUS delete_memory_creds(struct WINBINDD_MEMORY_CREDS *memcredp) #if !defined(HAVE_MUNLOCK) return NT_STATUS_OK; #else - int psize = getpagesize(); - - if (munlock(memcredp->buffer, memcredp->len - psize) == -1) { + if (munlock(memcredp->nt_hash, memcredp->len) == -1) { DEBUG(0,("failed to munlock memory: %s (%d)\n", strerror(errno), errno)); return map_nt_error_from_unix(errno); } - memset(memcredp->buffer, '\0', memcredp->len); - TALLOC_FREE(memcredp->buffer); + memset(memcredp->nt_hash, '\0', memcredp->len); + SAFE_FREE(memcredp->nt_hash); memcredp->nt_hash = NULL; memcredp->lm_hash = NULL; memcredp->pass = NULL; diff --git a/source/nsswitch/winbindd_nss.h b/source/nsswitch/winbindd_nss.h index 919575d9576..b6c262e4667 100644 --- a/source/nsswitch/winbindd_nss.h +++ b/source/nsswitch/winbindd_nss.h @@ -469,8 +469,6 @@ struct WINBINDD_MEMORY_CREDS { uid_t uid; int ref_count; size_t len; - unsigned char *buffer; /* buffer block containing the - following 3 */ unsigned char *nt_hash; /* Base pointer for the following 2 */ unsigned char *lm_hash; char *pass; |