Mercurial > dropbear
annotate dbmalloc.c @ 1861:2b3a8026a6ce
Add re-exec for server
This allows ASLR to re-randomize the address
space for every connection, preventing some
vulnerabilities from being exploitable by
repeated probing.
Overhead (memory and time) is yet to be confirmed.
At present this is only enabled on Linux. Other BSD platforms
with fexecve() would probably also work though have not been tested.
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 30 Jan 2022 10:14:56 +0800 |
parents | 1051e4eea25a |
children |
rev | line source |
---|---|
1361 | 1 #include "dbmalloc.h" |
2 #include "dbutil.h" | |
3 | |
1569
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
4 |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
5 void * m_calloc(size_t nmemb, size_t size) { |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
6 if (SIZE_T_MAX / nmemb < size) { |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
7 dropbear_exit("m_calloc failed"); |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
8 } |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
9 return m_malloc(nmemb*size); |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
10 } |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
11 |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
12 void * m_strdup(const char * str) { |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
13 char* ret; |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
14 unsigned int len; |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
15 len = strlen(str); |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
16 |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
17 ret = m_malloc(len+1); |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
18 if (ret == NULL) { |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
19 dropbear_exit("m_strdup failed"); |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
20 } |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
21 memcpy(ret, str, len+1); |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
22 return ret; |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
23 } |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
24 |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
25 #if !DROPBEAR_TRACKING_MALLOC |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
26 |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
27 /* Simple wrappers around malloc etc */ |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
28 void * m_malloc(size_t size) { |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
29 |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
30 void* ret; |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
31 |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
32 if (size == 0) { |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
33 dropbear_exit("m_malloc failed"); |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
34 } |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
35 ret = calloc(1, size); |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
36 if (ret == NULL) { |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
37 dropbear_exit("m_malloc failed"); |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
38 } |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
39 return ret; |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
40 |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
41 } |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
42 |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
43 void * m_realloc(void* ptr, size_t size) { |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
44 |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
45 void *ret; |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
46 |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
47 if (size == 0) { |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
48 dropbear_exit("m_realloc failed"); |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
49 } |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
50 ret = realloc(ptr, size); |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
51 if (ret == NULL) { |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
52 dropbear_exit("m_realloc failed"); |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
53 } |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
54 return ret; |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
55 } |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
56 |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
57 |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
58 #else |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
59 |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
60 /* For fuzzing */ |
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
61 |
1361 | 62 struct dbmalloc_header { |
63 unsigned int epoch; | |
1378 | 64 struct dbmalloc_header *prev; |
65 struct dbmalloc_header *next; | |
1361 | 66 }; |
67 | |
1378 | 68 static void put_alloc(struct dbmalloc_header *header); |
69 static void remove_alloc(struct dbmalloc_header *header); | |
70 | |
71 /* end of the linked list */ | |
72 static struct dbmalloc_header* staple; | |
1361 | 73 |
74 unsigned int current_epoch = 0; | |
75 | |
76 void m_malloc_set_epoch(unsigned int epoch) { | |
77 current_epoch = epoch; | |
78 } | |
79 | |
1378 | 80 void m_malloc_free_epoch(unsigned int epoch, int dofree) { |
81 struct dbmalloc_header* header; | |
82 struct dbmalloc_header* nextheader = NULL; | |
83 struct dbmalloc_header* oldstaple = staple; | |
84 staple = NULL; | |
85 /* free allocations from this epoch, create a new staple-anchored list from | |
86 the remainder */ | |
87 for (header = oldstaple; header; header = nextheader) | |
88 { | |
89 nextheader = header->next; | |
90 if (header->epoch == epoch) { | |
91 if (dofree) { | |
92 free(header); | |
1361 | 93 } |
1378 | 94 } else { |
95 header->prev = NULL; | |
96 header->next = NULL; | |
97 put_alloc(header); | |
1361 | 98 } |
99 } | |
100 } | |
101 | |
102 static void put_alloc(struct dbmalloc_header *header) { | |
1378 | 103 assert(header->next == NULL); |
104 assert(header->prev == NULL); | |
105 if (staple) { | |
106 staple->prev = header; | |
1361 | 107 } |
1378 | 108 header->next = staple; |
109 staple = header; | |
1361 | 110 } |
111 | |
112 static void remove_alloc(struct dbmalloc_header *header) { | |
1378 | 113 if (header->prev) { |
114 header->prev->next = header->next; | |
115 } | |
116 if (header->next) { | |
117 header->next->prev = header->prev; | |
118 } | |
119 if (staple == header) { | |
120 staple = header->next; | |
121 } | |
122 header->prev = NULL; | |
123 header->next = NULL; | |
1361 | 124 } |
125 | |
126 static struct dbmalloc_header* get_header(void* ptr) { | |
127 char* bptr = ptr; | |
128 return (struct dbmalloc_header*)&bptr[-sizeof(struct dbmalloc_header)]; | |
129 } | |
130 | |
131 void * m_malloc(size_t size) { | |
132 char* mem = NULL; | |
133 struct dbmalloc_header* header = NULL; | |
134 | |
135 if (size == 0 || size > 1e9) { | |
136 dropbear_exit("m_malloc failed"); | |
137 } | |
138 | |
139 size = size + sizeof(struct dbmalloc_header); | |
140 | |
141 mem = calloc(1, size); | |
142 if (mem == NULL) { | |
143 dropbear_exit("m_malloc failed"); | |
144 } | |
145 header = (struct dbmalloc_header*)mem; | |
146 put_alloc(header); | |
147 header->epoch = current_epoch; | |
148 return &mem[sizeof(struct dbmalloc_header)]; | |
149 } | |
150 | |
151 void * m_realloc(void* ptr, size_t size) { | |
152 char* mem = NULL; | |
153 struct dbmalloc_header* header = NULL; | |
154 if (size == 0 || size > 1e9) { | |
155 dropbear_exit("m_realloc failed"); | |
156 } | |
157 | |
158 header = get_header(ptr); | |
159 remove_alloc(header); | |
160 | |
161 size = size + sizeof(struct dbmalloc_header); | |
162 mem = realloc(header, size); | |
163 if (mem == NULL) { | |
164 dropbear_exit("m_realloc failed"); | |
165 } | |
166 | |
167 header = (struct dbmalloc_header*)mem; | |
168 put_alloc(header); | |
169 return &mem[sizeof(struct dbmalloc_header)]; | |
170 } | |
171 | |
172 void m_free_direct(void* ptr) { | |
173 struct dbmalloc_header* header = NULL; | |
174 if (!ptr) { | |
175 return; | |
176 } | |
177 header = get_header(ptr); | |
178 remove_alloc(header); | |
179 free(header); | |
180 } | |
181 | |
1569
c42e8ff42bd1
Only use malloc wrapper if fuzzing
Matt Johnston <matt@ucc.asn.au>
parents:
1378
diff
changeset
|
182 #endif /* DROPBEAR_TRACKING_MALLOC */ |
1692
1051e4eea25a
Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
1569
diff
changeset
|
183 |
1051e4eea25a
Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
1569
diff
changeset
|
184 void * m_realloc_ltm(void* ptr, size_t oldsize, size_t newsize) { |
1051e4eea25a
Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
1569
diff
changeset
|
185 (void)oldsize; |
1051e4eea25a
Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
1569
diff
changeset
|
186 return m_realloc(ptr, newsize); |
1051e4eea25a
Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
1569
diff
changeset
|
187 } |
1051e4eea25a
Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
1569
diff
changeset
|
188 |
1051e4eea25a
Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
1569
diff
changeset
|
189 void m_free_ltm(void *mem, size_t size) { |
1051e4eea25a
Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
1569
diff
changeset
|
190 (void)size; |
1051e4eea25a
Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
1569
diff
changeset
|
191 m_free_direct(mem); |
1051e4eea25a
Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
1569
diff
changeset
|
192 } |