Mercurial > dropbear
annotate dbmalloc.c @ 1622:e11ed628708b
- Add adaptive authentication failure delay
- Rework monotonic_now/gettime_wrapper and use clock_gettime on more platforms
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 05 Nov 2018 23:36:34 +0800 |
parents | c42e8ff42bd1 |
children | 1051e4eea25a |
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 */ |