1 #include <string.h>
2 #include <assert.h>
3 #include <signal.h>
4 #include <stdio.h>
5 #include <setjmp.h>
6
7 #include "vtv_malloc.h"
8 #include "../../../include/vtv-change-permission.h"
9
10 volatile static int signal_count = 0;
11
12 sigjmp_buf before_segv;
13
14 unsigned int vtv_debug = 0;
15
16 static void
handler(int sig,siginfo_t * si,void * unused)17 handler(int sig, siginfo_t *si, void *unused)
18 {
19 signal_count++;
20 /* You are not supposed to longjmp out of a signal handler but it seems
21 to work for this test case and it simplifies it */
22 siglongjmp(before_segv, 1);
23 }
24
25 /* Try to modify the memory pointed by "s" but dont actually change the values.
26 Assumes and verifies the memory to be modified is mprotected */
mempoke(void * s,size_t n)27 void mempoke(void * s, size_t n)
28 {
29 volatile char * p = (char *)s;
30 int ret;
31
32 signal_count = 0;
33 ret = sigsetjmp(before_segv, 1);
34 if (ret == 0)
35 p[0] = p[0];
36
37 assert(ret == 1 && signal_count == 1);
38
39 ret = sigsetjmp(before_segv, 1);
40 if (ret == 0)
41 p[n - 1] = p[n - 1];
42
43 assert(ret == 1 && signal_count == 2);
44 }
45
main()46 int main()
47 {
48 char * ptr;
49 int size;
50
51 /* Set up handler for SIGSEGV. */
52 struct sigaction sa;
53 sa.sa_flags = SA_SIGINFO;
54 sigemptyset(&sa.sa_mask);
55 sa.sa_sigaction = handler;
56 if (sigaction(SIGSEGV, &sa, NULL) == -1)
57 assert(0);
58
59 /* Make the 'bookkeeping' vars read-write. */
60 __VLTChangePermission (__VLTP_READ_WRITE);
61 __vtv_malloc_init();
62
63 size = 10;
64
65 /* Verify not writable after unprotect */
66 __vtv_malloc_unprotect();
67 ptr = (char *)__vtv_malloc(size);
68 memset(ptr, 'a', size);
69 __vtv_malloc_protect();
70 mempoke(ptr, size);
71 __vtv_free(ptr);
72
73 /* verify not-writable after protect, unprotect */
74 __vtv_malloc_unprotect();
75 ptr = (char *)__vtv_malloc(size);
76 memset(ptr, 'a', size);
77 __vtv_malloc_protect();
78 __vtv_malloc_unprotect();
79 memset(ptr, 'a', size);
80 assert(ptr[size - 1] == 'a');
81 __vtv_malloc_protect();
82 assert(ptr[size - 1] == 'a');
83 mempoke(ptr,size);
84 __vtv_free(ptr);
85
86 /* Allocate a bunch of small objects.
87 Make sure the alignment is correct.
88 Verify data has not been corrupted.
89 Make sure the data cannot modified */
90 {
91 int s;
92 for (s = 3; s < 28; s += 3)
93 {
94 size = s;
95 {
96 int i;
97 #define ITERS 1000
98 char * ptrs[ITERS];
99
100 __vtv_malloc_unprotect();
101 for (i = 0; i < ITERS; i++)
102 {
103 ptr = (char *)__vtv_malloc(size);
104 assert(((long)ptr & VTV_ALIGNMENT_MASK) == 0);
105 memset(ptr, (i & 127), size);
106 assert(ptr[size - 1] == (i & 127));
107 ptrs[i] = ptr;
108 }
109 __vtv_malloc_protect();
110
111 for (i = 0; i < ITERS; i++)
112 mempoke(ptrs[i], size);
113
114 __vtv_malloc_unprotect();
115 for (i = 0; i < ITERS; i++)
116 __vtv_free(ptrs[i]);
117 __vtv_malloc_protect();
118 }
119 }
120 }
121
122 /* Allocate a bunch of medium size objects.
123 Make sure the alignment is correct.
124 Verify data has not been corrupted.
125 Try to modify the data to verify everything gets unprotected */
126 {
127 int s;
128 for (s = 501; s < 2500; s += 91)
129 {
130 size = s;
131 {
132 int i;
133 #define ITERS2 100
134 char * ptrs[ITERS2];
135
136 __vtv_malloc_unprotect();
137 for (i = 0; i < ITERS2; i++)
138 {
139
140 ptr = (char *)__vtv_malloc(size);
141 assert(((long)ptr & VTV_ALIGNMENT_MASK) == 0);
142 memset(ptr, i & 127, size);
143 assert(ptr[size - 1] == i & 127);
144 ptrs[i] = ptr;
145 }
146 __vtv_malloc_protect();
147
148 for (i = 0; i < ITERS2; i++)
149 mempoke(ptrs[i], size);
150
151 __vtv_malloc_unprotect();
152 for (i = 0; i < ITERS2; i++)
153 __vtv_free(ptrs[i]);
154 __vtv_malloc_protect();
155 }
156 }
157 }
158
159 /* Allocate a bunch of medium size objects. Make sure the alignment is correct */
160 {
161 int s;
162 for (s = 3001; s < 15000; s += 307)
163 {
164 size = s;
165 {
166 int i;
167 #define ITERS3 50
168 char * ptrs[ITERS3];
169
170 __vtv_malloc_unprotect();
171 for (i = 0; i < ITERS3; i++)
172 {
173 ptr = (char *)__vtv_malloc(size);
174 assert(((long)ptr & VTV_ALIGNMENT_MASK) == 0);
175 memset(ptr, i & 127, size);
176 assert(ptr[size - 1] == i & 127);
177 ptrs[i] = ptr;
178 }
179 __vtv_malloc_protect();
180
181 for (i = 0; i < ITERS3; i++)
182 mempoke(ptrs[i], size);
183
184 __vtv_malloc_unprotect();
185 for (i = 0; i < ITERS3; i++)
186 __vtv_free(ptrs[i]);
187 __vtv_malloc_protect();
188 }
189 }
190 }
191
192 return 0;
193 }
194