summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/configure.in1
-rw-r--r--source/include/smb_macros.h1
-rw-r--r--source/lib/system.c21
-rw-r--r--source/lib/util.c28
-rw-r--r--source/nsswitch/winbindd_cred_cache.c30
-rw-r--r--source/nsswitch/winbindd_nss.h2
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;