ObjFW  Check-in [75ec6edab2]

Overview
Comment:+[OFSecureData isSecure]: Check for EPERM
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 75ec6edab2ea0c8149ad4c018d600822b60826d2ff5c4d1aa15920dd1f0beba9
User & Date: js on 2018-04-08 20:28:27
Other Links: manifest | tags
Context
2018-04-08
22:36
configure: Make sure -lpsplibc comes after -lgcc check-in: 0f6937eba9 user: js tags: trunk
20:28
+[OFSecureData isSecure]: Check for EPERM check-in: 75ec6edab2 user: js tags: trunk
19:32
exception.m: Handle read of unaligned values check-in: 681e1a13f3 user: js tags: trunk
Changes

Modified src/OFSecureData.m from [43dbd361d6] to [8841787590].

13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"


#include <stdlib.h>

#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#endif

#import "OFSecureData.h"
#import "OFString.h"
#import "OFSystemInfo.h"

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"

#ifdef OF_HAVE_THREADS
# import "threading.h"
#endif

#define CHUNK_SIZE 32

struct page {
	struct page *next, *previous;
	void *map;
	unsigned char *page;
};








>



















|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#include <errno.h>
#include <stdlib.h>

#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#endif

#import "OFSecureData.h"
#import "OFString.h"
#import "OFSystemInfo.h"

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"

#ifdef OF_HAVE_THREADS
# import "threading.h"
#endif

#define CHUNK_SIZE 16

struct page {
	struct page *next, *previous;
	void *map;
	unsigned char *page;
};

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON)
	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)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: pageSize];
#else
	if ((pointer = malloc(numPages * pageSize)) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: pageSize];
#endif







|







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON)
	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 && errno != EPERM)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: pageSize];
#else
	if ((pointer = malloc(numPages * pageSize)) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: pageSize];
#endif
237
238
239
240
241
242
243























244
245
246
247
248
249
250
251
		    exceptionWithClass: self];
}
#endif

+ (bool)isSecure
{
#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON)























	return true;
#else
	return false;
#endif
}

+ (instancetype)dataWithCount: (size_t)count
{







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
		    exceptionWithClass: self];
}
#endif

+ (bool)isSecure
{
#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON)
	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
}

+ (instancetype)dataWithCount: (size_t)count
{
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
- (void)dealloc
{
	size_t pageSize = [OFSystemInfo pageSize];

	if (_count * _itemSize > pageSize)
		unmapPages(_items,
		    OF_ROUND_UP_POW2(pageSize, _count * _itemSize) / pageSize);
	else {
		if (_items != NULL)
			freeMemory(_page, _items, _count * _itemSize);

		removePageIfEmpty(_page);
	}

	[super dealloc];







|







426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
- (void)dealloc
{
	size_t pageSize = [OFSystemInfo pageSize];

	if (_count * _itemSize > pageSize)
		unmapPages(_items,
		    OF_ROUND_UP_POW2(pageSize, _count * _itemSize) / pageSize);
	else if (_page != NULL) {
		if (_items != NULL)
			freeMemory(_page, _items, _count * _itemSize);

		removePageIfEmpty(_page);
	}

	[super dealloc];