Index: src/OFSecureData.m ================================================================== --- src/OFSecureData.m +++ src/OFSecureData.m @@ -15,10 +15,11 @@ * file. */ #include "config.h" +#include #include #ifdef HAVE_SYS_MMAN_H # include #endif @@ -34,11 +35,11 @@ #ifdef OF_HAVE_THREADS # import "threading.h" #endif -#define CHUNK_SIZE 32 +#define CHUNK_SIZE 16 struct page { struct page *next, *previous; void *map; unsigned char *page; @@ -67,11 +68,11 @@ if ((pointer = mmap(NULL, numPages * pageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0)) == MAP_FAILED) @throw [OFOutOfMemoryException exceptionWithRequestedSize: pageSize]; - if (mlock(pointer, numPages * pageSize) != 0) + if (mlock(pointer, numPages * pageSize) != 0 && errno != EPERM) @throw [OFOutOfMemoryException exceptionWithRequestedSize: pageSize]; #else if ((pointer = malloc(numPages * pageSize)) == NULL) @throw [OFOutOfMemoryException @@ -239,11 +240,34 @@ #endif + (bool)isSecure { #if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON) - return true; + bool isSecure = true; + size_t pageSize = [OFSystemInfo pageSize]; + void *pointer; + + if ((pointer = mmap(NULL, pageSize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0)) == MAP_FAILED) + @throw [OFOutOfMemoryException + exceptionWithRequestedSize: pageSize]; + + if (mlock(pointer, pageSize) != 0) { + if (errno != EPERM) { + munmap(pointer, pageSize); + + @throw [OFOutOfMemoryException + exceptionWithRequestedSize: pageSize]; + } + + isSecure = false; + } + + munlock(pointer, pageSize); + munmap(pointer, pageSize); + + return isSecure; #else return false; #endif } @@ -404,11 +428,11 @@ size_t pageSize = [OFSystemInfo pageSize]; if (_count * _itemSize > pageSize) unmapPages(_items, OF_ROUND_UP_POW2(pageSize, _count * _itemSize) / pageSize); - else { + else if (_page != NULL) { if (_items != NULL) freeMemory(_page, _items, _count * _itemSize); removePageIfEmpty(_page); }