memory corruption from mlock() changes
Gerald (Jerry) Carter
jerry at samba.org
Fri Feb 23 17:11:56 GMT 2007
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Guenther,
Gerald (Jerry) Carter wrote:
> Please try this patch that converts the talloc()'d memory
> to a malloc() before trying to mlock() it. This clears
> up the crash and hangs on my Ubuntu systems. Should be fine
> on my Solaris box as well but I've yet to test that.
>
> If this works we could also convert to memalign as
> James suggested but would need to add configure tests
> I assume. This is a simpler change for now.
New patch using memalign (or posix_memalign() depending
on what is available). I tested my local tree on Linux
and Solaris. Haven't tested this port to SAMBA_3_0 but
hopefully I didn't do anything stupid in the merge.
cheers, jerry
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.4 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFF3yBcIR7qMdg1EfYRAg//AJoCL9QbAS+O8Zm7pnuSVaUjA3qyCQCgmW+J
2laBJnMggrGJ1twX32ssUgo=
=y8oP
-----END PGP SIGNATURE-----
-------------- next part --------------
Index: nsswitch/winbindd_cred_cache.c
===================================================================
--- nsswitch/winbindd_cred_cache.c (revision 21520)
+++ nsswitch/winbindd_cred_cache.c (working copy)
@@ -482,29 +482,21 @@
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 */
+ /* On non-linux platforms, mlock()'d memory must be aligned */
- memcredp->len += psize;
-
- memcredp->buffer = (unsigned char*)TALLOC_ZERO(memcredp, memcredp->len);
-
- if (!memcredp->buffer) {
+ memcredp->nt_hash = SMB_MEMALIGN_ARRAY(unsigned char*, psize,
+ memcredp->len);
+ if (!memcredp->nt_hash) {
return NT_STATUS_NO_MEMORY;
}
-
+ memset( memcredp->nt_hash, 0x0, memcredp->len );
- /* point the nt_hash at the page boundary in the buffer */
-
- 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 @@
#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: nsswitch/winbindd_nss.h
===================================================================
--- nsswitch/winbindd_nss.h (revision 21520)
+++ nsswitch/winbindd_nss.h (working copy)
@@ -469,8 +469,6 @@
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;
Index: lib/util.c
===================================================================
--- lib/util.c (revision 21520)
+++ lib/util.c (working copy)
@@ -913,6 +913,17 @@
}
/****************************************************************************
+ 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 @@
}
/****************************************************************************
+ 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: lib/system.c
===================================================================
--- lib/system.c (revision 21520)
+++ lib/system.c (working copy)
@@ -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.
********************************************************************/
Index: include/smb_macros.h
===================================================================
--- include/smb_macros.h (revision 21520)
+++ include/smb_macros.h (working copy)
@@ -276,6 +276,7 @@
*****************************************************************************/
#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: configure.in
===================================================================
--- configure.in (revision 21520)
+++ configure.in (working copy)
@@ -1240,6 +1240,7 @@
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)
More information about the samba-technical
mailing list