r21525: Go ahead and checkin the mlock() & memalign() fixes so
authorGerald Carter <jerry@samba.org>
Sat, 24 Feb 2007 12:40:43 +0000 (12:40 +0000)
committerGerald Carter <jerry@samba.org>
Sat, 24 Feb 2007 12:40:43 +0000 (12:40 +0000)
others don't get stuck with the winbindd hang.
Still waiting on additional confirmation from Guenther
that this fixes thes issues he was observing as well.
But it's been running in my local tree for a day without
problems.

source/configure.in
source/include/smb_macros.h
source/lib/system.c
source/lib/util.c
source/nsswitch/winbindd_cred_cache.c
source/nsswitch/winbindd_nss.h

index b866308adbacb4fce5b91df51f3571c9fe8a3496..9b53cd388684ef9d4a17cd3e3860ea332eee2b7e 100644 (file)
@@ -1236,6 +1236,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)
index 0fa6f132db2063c094e55a8d7028783f3d4320ce..add7dcd31c263fd3ecc29664a15e21939f3f8c4c 100644 (file)
@@ -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 */
index 9ee3f7cc26afc782548dad80c1e7780c8ce417c8..5e70fb8ac5e3f5f24dd6cc21cc2d934f5179f710 100644 (file)
 
 
 
+/*******************************************************************
+ 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"));\13
+       return NULL;
+#endif
+}
+
 /*******************************************************************
  A wrapper for usleep in case we don't have one.
 ********************************************************************/
index 7d41a14292c69e9c7e7e6580a661bf7bb98dd5eb..5f9eb4fc4502c19e956673dd5ab4037e44ddc519 100644 (file)
@@ -912,6 +912,17 @@ void *malloc_(size_t size)
 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
 }
 
+/****************************************************************************
+ 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.
 ****************************************************************************/
@@ -953,6 +964,23 @@ void *malloc_array(size_t el_size, unsigned int count)
 #endif
 }
 
+/****************************************************************************
+ 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.
 ****************************************************************************/
index 8dc8fab4ac140fb3c1b3bf7048582957a62e7c45..bd2798d68bc18b09e19406565daf996b3d4aec82 100644 (file)
@@ -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;
index 919575d95765de239baf9b76ef7a82f2fc150c35..b6c262e466799a3cf4c247d3a4de2c08ab541eb9 100644 (file)
@@ -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;