2 * Part of Very Secure FTPd
7 * Here are some routines providing the (possibly silly) concept of a secure
8 * buffer. A secure buffer may not be overflowed. A single byte overflow
9 * will cause the program to safely terminate.
15 #include "sysdeputil.h"
18 vsf_secbuf_alloc(char** p_ptr
, unsigned int size
)
20 unsigned int page_offset
;
21 unsigned int round_up
;
23 char* p_no_access_page
;
24 unsigned int page_size
= vsf_sysutil_getpagesize();
26 /* Free any previous buffer */
27 vsf_secbuf_free(p_ptr
);
28 /* Round up to next page size */
29 page_offset
= size
% page_size
;
32 unsigned int num_pages
= size
/ page_size
;
34 round_up
= num_pages
* page_size
;
38 /* Allocation is on a page-size boundary */
41 /* Add on another two pages to make inaccessible */
42 round_up
+= page_size
* 2;
44 p_mmap
= vsf_sysutil_map_anon_pages(round_up
);
45 /* Map the first and last page inaccessible */
46 p_no_access_page
= p_mmap
+ round_up
- page_size
;
47 vsf_sysutil_memprotect(p_no_access_page
, page_size
, kVSFSysUtilMapProtNone
);
48 /* Before we make the "before" page inaccessible, store the size in it.
49 * A little hack so that we don't need to explicitly be passed the size
50 * when freeing an existing secure buffer
52 *((unsigned int*)p_mmap
) = round_up
;
53 p_no_access_page
= p_mmap
;
54 vsf_sysutil_memprotect(p_no_access_page
, page_size
, kVSFSysUtilMapProtNone
);
59 p_mmap
+= (page_size
- page_offset
);
65 vsf_secbuf_free(char** p_ptr
)
67 unsigned int map_size
;
68 unsigned long page_offset
;
69 char* p_mmap
= *p_ptr
;
70 unsigned int page_size
= vsf_sysutil_getpagesize();
75 /* Calculate the actual start of the mmap region */
76 page_offset
= (unsigned long) p_mmap
% page_size
;
79 p_mmap
-= page_offset
;
82 /* First make the first page readable so we can get the size */
83 vsf_sysutil_memprotect(p_mmap
, page_size
, kVSFSysUtilMapProtReadOnly
);
84 /* Extract the mapping size */
85 map_size
= *((unsigned int*)p_mmap
);
86 /* Lose the mapping */
87 vsf_sysutil_memunmap(p_mmap
, map_size
);