From 504bb62b23d9a9691fed137abbb5e3b2f1c18b72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 22 Feb 2007 17:21:27 +0000 Subject: r21505: make sure mlock()'d memory is aligned on a page boundary --- source/nsswitch/winbindd_cred_cache.c | 31 ++++++++++++++++++++++++------- source/nsswitch/winbindd_nss.h | 2 ++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/source/nsswitch/winbindd_cred_cache.c b/source/nsswitch/winbindd_cred_cache.c index 50d39dd670b..8dc8fab4ac1 100644 --- a/source/nsswitch/winbindd_cred_cache.c +++ b/source/nsswitch/winbindd_cred_cache.c @@ -471,6 +471,8 @@ static NTSTATUS store_memory_creds(struct WINBINDD_MEMORY_CREDS *memcredp, const #if !defined(HAVE_MLOCK) return NT_STATUS_OK; #else + int psize = getpagesize(); + /* new_entry->nt_hash is the base pointer for the block of memory pointed into by new_entry->lm_hash and new_entry->pass (if we're storing plaintext). */ @@ -480,17 +482,29 @@ static NTSTATUS store_memory_creds(struct WINBINDD_MEMORY_CREDS *memcredp, const memcredp->len += strlen(pass)+1; } - memcredp->nt_hash = (unsigned char *)TALLOC_ZERO(memcredp, memcredp->len); - if (!memcredp->nt_hash) { + /* 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) { return NT_STATUS_NO_MEMORY; } + + + /* 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)) == -1) { + if ((mlock(memcredp->nt_hash, memcredp->len-psize)) == -1) { DEBUG(0,("failed to mlock memory: %s (%d)\n", strerror(errno), errno)); return map_nt_error_from_unix(errno); @@ -522,13 +536,16 @@ static NTSTATUS delete_memory_creds(struct WINBINDD_MEMORY_CREDS *memcredp) #if !defined(HAVE_MUNLOCK) return NT_STATUS_OK; #else - if (munlock(memcredp->nt_hash, memcredp->len) == -1) { + int psize = getpagesize(); + + if (munlock(memcredp->buffer, memcredp->len - psize) == -1) { DEBUG(0,("failed to munlock memory: %s (%d)\n", strerror(errno), errno)); return map_nt_error_from_unix(errno); } - memset(memcredp->nt_hash, '\0', memcredp->len); - TALLOC_FREE(memcredp->nt_hash); + memset(memcredp->buffer, '\0', memcredp->len); + TALLOC_FREE(memcredp->buffer); + memcredp->nt_hash = NULL; memcredp->lm_hash = NULL; memcredp->pass = NULL; memcredp->len = 0; diff --git a/source/nsswitch/winbindd_nss.h b/source/nsswitch/winbindd_nss.h index b6c262e4667..919575d9576 100644 --- a/source/nsswitch/winbindd_nss.h +++ b/source/nsswitch/winbindd_nss.h @@ -469,6 +469,8 @@ 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; -- cgit v1.2.1