diff options
author | doug <> | 2014-10-19 17:58:14 +0000 |
---|---|---|
committer | doug <> | 2014-10-19 17:58:14 +0000 |
commit | 4df28d31f8d900d5d1d164c0c75e270e82e11e81 (patch) | |
tree | a4649fb344da28a3c612e514e4c96cbb473efdeb /src | |
parent | 166117897f0e1f5aef7866f9e8eb9672a27313ab (diff) | |
download | openbsd-4df28d31f8d900d5d1d164c0c75e270e82e11e81.tar.gz openbsd-4df28d31f8d900d5d1d164c0c75e270e82e11e81.tar.bz2 openbsd-4df28d31f8d900d5d1d164c0c75e270e82e11e81.zip |
Revamp malloc.3 by reordering the sections and rewriting parts.
The old man page had a lot of useful information, but it was all mixed
together which made it difficult to reference. The main theme in this
commit is that the sections are more focused:
* DESCRIPTION describes the overall behavior
* RETURN VALUES describes what it may return (including implementation
defined values)
* EXAMPLES shows why we recently started an audit on malloc and realloc
usage in the tree.
* Added CAVEATS which describes what is implementation defined, gotchas
and security implications of misusing these functions
* Added IDIOMS which describes how these functions should or
should not be used
The MALLOC_OPTIONS section was left unchanged. Function names were
added to DIAGNOSTICS and STANDARDS. The MALLOC_OPTIONS and DIAGNOSTICS
sections were pushed down in the page so more pertinent information is
higher up.
This has gone through several revisions thanks to input from deraadt@
and schwarze@. Ingo also helped with some of the mandoc formatting.
OK schwarze@ (as far as it is a good starting point and the code
snippets look ok)
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libc/stdlib/malloc.3 | 602 |
1 files changed, 417 insertions, 185 deletions
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3 index d738524c81..4185648c84 100644 --- a/src/lib/libc/stdlib/malloc.3 +++ b/src/lib/libc/stdlib/malloc.3 | |||
@@ -30,9 +30,9 @@ | |||
30 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 30 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
31 | .\" SUCH DAMAGE. | 31 | .\" SUCH DAMAGE. |
32 | .\" | 32 | .\" |
33 | .\" $OpenBSD: malloc.3,v 1.78 2014/05/01 18:41:59 jmc Exp $ | 33 | .\" $OpenBSD: malloc.3,v 1.79 2014/10/19 17:58:14 doug Exp $ |
34 | .\" | 34 | .\" |
35 | .Dd $Mdocdate: May 1 2014 $ | 35 | .Dd $Mdocdate: October 19 2014 $ |
36 | .Dt MALLOC 3 | 36 | .Dt MALLOC 3 |
37 | .Os | 37 | .Os |
38 | .Sh NAME | 38 | .Sh NAME |
@@ -65,58 +65,15 @@ The | |||
65 | function allocates uninitialized space for an object whose | 65 | function allocates uninitialized space for an object whose |
66 | size is specified by | 66 | size is specified by |
67 | .Fa size . | 67 | .Fa size . |
68 | The | ||
69 | .Fn malloc | 68 | .Fn malloc |
70 | function maintains multiple lists of free blocks according to size, allocating | 69 | maintains multiple lists of free blocks according to size, allocating |
71 | space from the appropriate list. | 70 | space from the appropriate list. |
72 | .Pp | 71 | The allocated space is suitably aligned (after possible pointer coercion) for |
73 | The allocated space is | 72 | storage of any type of object. |
74 | suitably aligned (after possible pointer | ||
75 | coercion) for storage of any type of object. | ||
76 | If the space is of | 73 | If the space is of |
77 | .Em pagesize | 74 | .Em pagesize |
78 | or larger, the memory returned will be page-aligned. | 75 | or larger, the memory returned will be page-aligned. |
79 | .Pp | 76 | .Pp |
80 | Allocation of a zero size object returns a pointer to a zero size object. | ||
81 | This zero size object is access protected, so any access to it will | ||
82 | generate an exception (SIGSEGV). | ||
83 | Many zero-sized objects can be placed consecutively in shared | ||
84 | protected pages. | ||
85 | The minimum size of the protection on each object is suitably aligned and | ||
86 | sized as previously stated, but the protection may extend further depending | ||
87 | on where in a protected zone the object lands. | ||
88 | .Pp | ||
89 | When using | ||
90 | .Fn malloc | ||
91 | be careful to avoid the following idiom: | ||
92 | .Bd -literal -offset indent | ||
93 | if ((p = malloc(num * size)) == NULL) | ||
94 | err(1, "malloc"); | ||
95 | .Ed | ||
96 | .Pp | ||
97 | The multiplication may lead to an integer overflow, which can | ||
98 | be avoided using the extension | ||
99 | .Fn reallocarray , | ||
100 | as follows: | ||
101 | .Bd -literal -offset indent | ||
102 | if ((p = reallocarray(NULL, num, size)) == NULL) | ||
103 | err(1, "malloc"); | ||
104 | .Ed | ||
105 | .Pp | ||
106 | Alternatively | ||
107 | .Fn calloc | ||
108 | is a more portable solution which comes with the cost of clearing memory. | ||
109 | .Pp | ||
110 | If | ||
111 | .Fn malloc | ||
112 | must be used, be sure to test for overflow: | ||
113 | .Bd -literal -offset indent | ||
114 | if (size && num > SIZE_MAX / size) { | ||
115 | errno = ENOMEM; | ||
116 | err(1, "overflow"); | ||
117 | } | ||
118 | .Ed | ||
119 | .Pp | ||
120 | The | 77 | The |
121 | .Fn calloc | 78 | .Fn calloc |
122 | function allocates space for an array of | 79 | function allocates space for an array of |
@@ -124,12 +81,35 @@ function allocates space for an array of | |||
124 | objects, each of whose size is | 81 | objects, each of whose size is |
125 | .Fa size . | 82 | .Fa size . |
126 | The space is initialized to zero. | 83 | The space is initialized to zero. |
127 | The use of | 84 | .Pp |
85 | The | ||
86 | .Fn realloc | ||
87 | function changes the size of the object pointed to by | ||
88 | .Fa ptr | ||
89 | to | ||
90 | .Fa size | ||
91 | bytes and returns a pointer to the (possibly moved) object. | ||
92 | The contents of the object are unchanged up to the lesser | ||
93 | of the new and old sizes. | ||
94 | If the new size is larger, the value of the newly allocated portion | ||
95 | of the object is indeterminate and uninitialized. | ||
96 | If the space cannot be allocated, the object | ||
97 | pointed to by | ||
98 | .Fa ptr | ||
99 | is unchanged. | ||
100 | .Pp | ||
101 | The | ||
128 | .Fn reallocarray | 102 | .Fn reallocarray |
129 | or | 103 | function is similar to |
130 | .Fn calloc | 104 | .Fn realloc |
131 | is strongly encouraged when allocating multiple sized objects | 105 | except it operates on |
132 | in order to avoid possible integer overflows. | 106 | .Fa nmemb |
107 | members of size | ||
108 | .Fa size | ||
109 | and checks for integer overflow in | ||
110 | .Fa nmemb | ||
111 | * | ||
112 | .Fa size . | ||
133 | .Pp | 113 | .Pp |
134 | The | 114 | The |
135 | .Fn free | 115 | .Fn free |
@@ -140,7 +120,17 @@ allocation or, if required, to be returned to the kernel using | |||
140 | .Xr munmap 2 . | 120 | .Xr munmap 2 . |
141 | If | 121 | If |
142 | .Fa ptr | 122 | .Fa ptr |
143 | is a null pointer, no action occurs. | 123 | is a |
124 | .Dv NULL | ||
125 | pointer, no action occurs. | ||
126 | If | ||
127 | .Fa ptr | ||
128 | was previously freed by | ||
129 | .Fn free | ||
130 | .Fn realloc , | ||
131 | or | ||
132 | .Fn reallocarray , | ||
133 | the behavior is undefined and the double free is a security concern. | ||
144 | .Pp | 134 | .Pp |
145 | A | 135 | A |
146 | .Fn cfree | 136 | .Fn cfree |
@@ -148,38 +138,135 @@ function is also provided for compatibility with old systems and other | |||
148 | .Nm malloc | 138 | .Nm malloc |
149 | libraries; it is simply an alias for | 139 | libraries; it is simply an alias for |
150 | .Fn free . | 140 | .Fn free . |
141 | .Sh RETURN VALUES | ||
142 | If | ||
143 | .Fn malloc , | ||
144 | .Fn calloc , | ||
145 | .Fn realloc , | ||
146 | or | ||
147 | .Fn reallocarray | ||
148 | is called with | ||
149 | .Fa size | ||
150 | or | ||
151 | .Fa nmemb | ||
152 | is equal to 0, | ||
153 | a pointer to an access protected, zero sized object is returned. | ||
154 | .Pp | ||
155 | If | ||
156 | .Fn malloc | ||
157 | is called with | ||
158 | .Fa size | ||
159 | greater than 0, it returns a pointer to the allocated space if successful; | ||
160 | otherwise, a | ||
161 | .Dv NULL | ||
162 | pointer is returned and | ||
163 | .Va errno | ||
164 | is set to | ||
165 | .Er ENOMEM . | ||
151 | .Pp | 166 | .Pp |
152 | The | 167 | The |
153 | .Fn realloc | 168 | .Fn calloc |
154 | function changes the size of the object pointed to by | 169 | function checks for integer overflow and returns |
155 | .Fa ptr | 170 | .Dv NULL |
156 | to | 171 | if |
172 | .Fa nmemb | ||
173 | * | ||
157 | .Fa size | 174 | .Fa size |
158 | bytes and returns a pointer to the (possibly moved) object. | 175 | will result in integer overflow. |
159 | The contents of the object are unchanged up to the lesser | ||
160 | of the new and old sizes. | ||
161 | If the new size is larger, the value of the newly allocated portion | ||
162 | of the object is indeterminate and uninitialized. | ||
163 | If | 176 | If |
164 | .Fa ptr | 177 | .Fa nmemb |
165 | is a null pointer, the | 178 | and |
179 | .Fa size | ||
180 | are greater than 0, | ||
181 | .Fn calloc | ||
182 | returns a pointer to the allocated space if successful; otherwise, a | ||
183 | .Dv NULL | ||
184 | pointer is returned and | ||
185 | .Va errno | ||
186 | is set to | ||
187 | .Er ENOMEM . | ||
188 | .Pp | ||
189 | The | ||
166 | .Fn realloc | 190 | .Fn realloc |
167 | function behaves like the | 191 | function behaves like |
168 | .Fn malloc | 192 | .Fn malloc |
169 | function for the specified size. | 193 | for the specified |
170 | If the space cannot be allocated, the object | 194 | .Fa size |
171 | pointed to by | 195 | when |
172 | .Fa ptr | 196 | .Fa ptr |
173 | is unchanged. | 197 | is |
198 | .Dv NULL . | ||
174 | If | 199 | If |
175 | .Fa size | 200 | .Fa size |
176 | is zero and | 201 | is greater than 0, |
177 | .Fa ptr | 202 | .Fn realloc |
178 | is not a null pointer, the object it points to is freed and a new zero size | 203 | returns a pointer to the allocated space if successful; otherwise, a |
179 | object is returned. | 204 | .Dv NULL |
205 | pointer is returned and | ||
206 | .Va errno | ||
207 | is set to | ||
208 | .Er ENOMEM . | ||
209 | .Pp | ||
210 | The | ||
211 | .Fn reallocarray | ||
212 | function checks for integer overflow and returns | ||
213 | .Dv NULL | ||
214 | if | ||
215 | .Fa nmemb | ||
216 | * | ||
217 | .Fa size | ||
218 | will result in integer overflow. | ||
219 | If | ||
220 | .Fn reallocarray | ||
221 | is called with | ||
222 | .Fa size | ||
223 | and | ||
224 | .Fa nmemb | ||
225 | greater than 0, it returns a pointer to the allocated space if successful; | ||
226 | otherwise, a | ||
227 | .Dv NULL | ||
228 | pointer is returned and | ||
229 | .Va errno | ||
230 | is set to | ||
231 | .Er ENOMEM . | ||
232 | .Pp | ||
233 | The | ||
234 | .Fn free | ||
235 | and | ||
236 | .Fn cfree | ||
237 | functions return no value. | ||
238 | .Sh IDIOMS | ||
239 | Consider | ||
240 | .Fn calloc | ||
241 | or the extension | ||
242 | .Fn reallocarray | ||
243 | when you have multiplication in the | ||
244 | .Fa size | ||
245 | argument of | ||
246 | .Fn malloc | ||
247 | or | ||
248 | .Fn realloc . | ||
249 | For example, avoid this common idiom as it may lead to integer overflow: | ||
250 | .Bd -literal -offset indent | ||
251 | if ((p = malloc(num * size)) == NULL) | ||
252 | err(1, "malloc"); | ||
253 | .Ed | ||
254 | .Pp | ||
255 | A drop-in replacement is the | ||
256 | .Ox | ||
257 | extension | ||
258 | .Fn reallocarray : | ||
259 | .Bd -literal -offset indent | ||
260 | if ((p = reallocarray(NULL, num, size)) == NULL) | ||
261 | err(1, "reallocarray"); | ||
262 | .Ed | ||
263 | .Pp | ||
264 | Alternatively, | ||
265 | .Fn calloc | ||
266 | may be used at the cost of initialization overhead. | ||
180 | .Pp | 267 | .Pp |
181 | When using | 268 | When using |
182 | .Fn realloc | 269 | .Fn realloc , |
183 | be careful to avoid the following idiom: | 270 | be careful to avoid the following idiom: |
184 | .Bd -literal -offset indent | 271 | .Bd -literal -offset indent |
185 | size += 50; | 272 | size += 50; |
@@ -208,13 +295,187 @@ size = newsize; | |||
208 | .Ed | 295 | .Ed |
209 | .Pp | 296 | .Pp |
210 | As with | 297 | As with |
211 | .Fn malloc | 298 | .Fn malloc , |
212 | it is important to ensure the new size value will not overflow; | 299 | it is important to ensure the new size value will not overflow; |
213 | i.e. avoid allocations like the following: | 300 | i.e. avoid allocations like the following: |
214 | .Bd -literal -offset indent | 301 | .Bd -literal -offset indent |
215 | if ((newp = realloc(p, num * size)) == NULL) { | 302 | if ((newp = realloc(p, num * size)) == NULL) { |
216 | ... | 303 | ... |
217 | .Ed | 304 | .Ed |
305 | .Pp | ||
306 | Instead, use | ||
307 | .Fn reallocarray : | ||
308 | .Bd -literal -offset indent | ||
309 | if ((newp = reallocarray(p, num, size)) == NULL) { | ||
310 | ... | ||
311 | .Ed | ||
312 | .Pp | ||
313 | Code designed for some ancient platforms avoided calling | ||
314 | .Fn realloc | ||
315 | with a | ||
316 | .Dv NULL | ||
317 | .Fa ptr . | ||
318 | Such hacks are no longer necessary in modern code. Instead of | ||
319 | this idiom: | ||
320 | .Bd -literal -offset indent | ||
321 | if (p == NULL) | ||
322 | newp = malloc(newsize); | ||
323 | else | ||
324 | newp = realloc(p, newsize); | ||
325 | .Ed | ||
326 | .Pp | ||
327 | Use the following as calling | ||
328 | .Fn realloc | ||
329 | with | ||
330 | .Dv NULL | ||
331 | is equivalent to calling | ||
332 | .Fn malloc : | ||
333 | .Bd -literal -offset indent | ||
334 | newp = realloc(p, newsize); | ||
335 | .Ed | ||
336 | .Sh ENVIRONMENT | ||
337 | .Bl -tag -width Ev | ||
338 | .It Ev MALLOC_OPTIONS | ||
339 | See below. | ||
340 | .El | ||
341 | .Sh FILES | ||
342 | .Bl -tag -width "/etc/malloc.conf" | ||
343 | .It Pa /etc/malloc.conf | ||
344 | symbolic link to filename containing option flags | ||
345 | .El | ||
346 | .Sh EXAMPLES | ||
347 | If | ||
348 | .Fn malloc | ||
349 | must be used with multiplication, be sure to test for overflow: | ||
350 | .Bd -literal -offset indent | ||
351 | size_t size; | ||
352 | size_t num; | ||
353 | \&... | ||
354 | |||
355 | /* Check for size_t overflow */ | ||
356 | if (size && num > SIZE_MAX / size) { | ||
357 | errno = EOVERFLOW; | ||
358 | err(1, "overflow"); | ||
359 | } | ||
360 | if ((p = malloc(size * num)) == NULL) | ||
361 | err(1, "malloc"); | ||
362 | .Ed | ||
363 | .Pp | ||
364 | The above test is not sufficient in all cases. For example, multiplying | ||
365 | ints requires a different set of checks: | ||
366 | .Bd -literal -offset indent | ||
367 | int size; | ||
368 | int num; | ||
369 | \&... | ||
370 | |||
371 | /* Avoid invalid requests */ | ||
372 | if (size < 0 || num < 0) { | ||
373 | errno = EOVERFLOW; | ||
374 | err(1, "overflow"); | ||
375 | } | ||
376 | |||
377 | /* Check for signed int overflow */ | ||
378 | if (size && num > INT_MAX / size) { | ||
379 | errno = EOVERFLOW; | ||
380 | err(1, "overflow"); | ||
381 | } | ||
382 | |||
383 | if ((p = malloc(size * num)) == NULL) | ||
384 | err(1, "malloc"); | ||
385 | .Ed | ||
386 | .Pp | ||
387 | Assuming the implementation checks for integer overflow as | ||
388 | .Ox | ||
389 | does, it is much easier to use | ||
390 | .Fn calloc | ||
391 | or | ||
392 | .Fn reallocarray . | ||
393 | .Pp | ||
394 | The above examples could be simplified to: | ||
395 | .Bd -literal -offset indent | ||
396 | if ((p = reallocarray(NULL, num, size)) == NULL) | ||
397 | err(1, "reallocarray"); | ||
398 | .Ed | ||
399 | .Pp | ||
400 | or at the cost of initialization: | ||
401 | .Bd -literal -offset indent | ||
402 | if ((p = calloc(num, size)) == NULL) | ||
403 | err(1, "calloc"); | ||
404 | .Ed | ||
405 | .Sh DIAGNOSTICS | ||
406 | If | ||
407 | .Fn malloc , | ||
408 | .Fn calloc , | ||
409 | .Fn realloc , | ||
410 | .Fn reallocarray , | ||
411 | or | ||
412 | .Fn free | ||
413 | detect an error condition, | ||
414 | a message will be printed to file descriptor | ||
415 | 2 (not using stdio). | ||
416 | Errors will result in the process being aborted, | ||
417 | unless the | ||
418 | .Cm a | ||
419 | option has been specified. | ||
420 | .Pp | ||
421 | Here is a brief description of the error messages and what they mean: | ||
422 | .Bl -tag -width Ds | ||
423 | .It Dq out of memory | ||
424 | If the | ||
425 | .Cm X | ||
426 | option is specified it is an error for | ||
427 | .Fn malloc , | ||
428 | .Fn calloc , | ||
429 | .Fn realloc , | ||
430 | or | ||
431 | .Fn reallocarray | ||
432 | to return | ||
433 | .Dv NULL . | ||
434 | .It Dq malloc init mmap failed | ||
435 | This is a rather weird condition that is most likely to indicate a | ||
436 | seriously overloaded system or a ulimit restriction. | ||
437 | .It Dq bogus pointer (double free?) | ||
438 | An attempt to | ||
439 | .Fn free , | ||
440 | .Fn realloc , | ||
441 | or | ||
442 | .Fn reallocarray | ||
443 | an unallocated pointer was made. | ||
444 | .It Dq chunk is already free | ||
445 | There was an attempt to free a chunk that had already been freed. | ||
446 | .It Dq modified chunk-pointer | ||
447 | The pointer passed to | ||
448 | .Fn free , | ||
449 | .Fn realloc , | ||
450 | or | ||
451 | .Fn reallocarray | ||
452 | has been modified. | ||
453 | .It Dq recursive call | ||
454 | An attempt was made to call recursively into these functions, i.e., from a | ||
455 | signal handler. | ||
456 | This behavior is not supported. | ||
457 | In particular, signal handlers should | ||
458 | .Em not | ||
459 | use any of the | ||
460 | .Fn malloc | ||
461 | functions nor utilize any other functions which may call | ||
462 | .Fn malloc | ||
463 | (e.g., | ||
464 | .Xr stdio 3 | ||
465 | routines). | ||
466 | .It Dq unknown char in MALLOC_OPTIONS | ||
467 | We found something we didn't understand. | ||
468 | .It Dq malloc cache overflow/underflow | ||
469 | The internal malloc page cache has been corrupted. | ||
470 | .It Dq malloc free slot lost | ||
471 | The internal malloc page cache has been corrupted. | ||
472 | .It Dq guard size | ||
473 | An inconsistent guard size was detected. | ||
474 | .It any other error | ||
475 | .Fn malloc | ||
476 | detected an internal error; | ||
477 | consult sources and/or wizards. | ||
478 | .El | ||
218 | .Sh MALLOC_OPTIONS | 479 | .Sh MALLOC_OPTIONS |
219 | Malloc will first look for a symbolic link called | 480 | Malloc will first look for a symbolic link called |
220 | .Pa /etc/malloc.conf | 481 | .Pa /etc/malloc.conf |
@@ -335,122 +596,22 @@ are used, | |||
335 | it is buggy. | 596 | it is buggy. |
336 | .Pp | 597 | .Pp |
337 | The default number of free pages cached is 64. | 598 | The default number of free pages cached is 64. |
338 | .Sh RETURN VALUES | ||
339 | The | ||
340 | .Fn malloc , | ||
341 | .Fn reallocarray , | ||
342 | and | ||
343 | .Fn calloc | ||
344 | functions return a pointer to the allocated space if successful; otherwise, | ||
345 | a null pointer is returned and | ||
346 | .Va errno | ||
347 | is set to | ||
348 | .Er ENOMEM . | ||
349 | .Pp | ||
350 | The | ||
351 | .Fn free | ||
352 | and | ||
353 | .Fn cfree | ||
354 | functions return no value. | ||
355 | .Pp | ||
356 | The | ||
357 | .Fn realloc | ||
358 | function returns a pointer to the (possibly moved) allocated space | ||
359 | if successful; otherwise, a null pointer is returned and | ||
360 | .Va errno | ||
361 | is set to | ||
362 | .Er ENOMEM . | ||
363 | .Sh ENVIRONMENT | ||
364 | .Bl -tag -width Ev | ||
365 | .It Ev MALLOC_OPTIONS | ||
366 | See above. | ||
367 | .El | ||
368 | .Sh FILES | ||
369 | .Bl -tag -width "/etc/malloc.conf" | ||
370 | .It Pa /etc/malloc.conf | ||
371 | symbolic link to filename containing option flags | ||
372 | .El | ||
373 | .Sh DIAGNOSTICS | ||
374 | If | ||
375 | .Fn malloc , | ||
376 | .Fn calloc , | ||
377 | .Fn realloc , | ||
378 | or | ||
379 | .Fn free | ||
380 | detect an error condition, | ||
381 | a message will be printed to file descriptor | ||
382 | 2 (not using stdio). | ||
383 | Errors will result in the process being aborted, | ||
384 | unless the | ||
385 | .Cm a | ||
386 | option has been specified. | ||
387 | .Pp | ||
388 | Here is a brief description of the error messages and what they mean: | ||
389 | .Bl -tag -width Ds | ||
390 | .It Dq out of memory | ||
391 | If the | ||
392 | .Cm X | ||
393 | option is specified it is an error for | ||
394 | .Fn malloc , | ||
395 | .Fn calloc , | ||
396 | or | ||
397 | .Fn realloc | ||
398 | to return | ||
399 | .Dv NULL . | ||
400 | .It Dq malloc init mmap failed | ||
401 | This is a rather weird condition that is most likely to indicate a | ||
402 | seriously overloaded system or a ulimit restriction. | ||
403 | .It Dq bogus pointer (double free?) | ||
404 | An attempt to | ||
405 | .Fn free | ||
406 | or | ||
407 | .Fn realloc | ||
408 | an unallocated pointer was made. | ||
409 | .It Dq chunk is already free | ||
410 | There was an attempt to free a chunk that had already been freed. | ||
411 | .It Dq modified chunk-pointer | ||
412 | The pointer passed to | ||
413 | .Fn free | ||
414 | or | ||
415 | .Fn realloc | ||
416 | has been modified. | ||
417 | .It Dq recursive call | ||
418 | An attempt was made to call recursively into these functions, i.e., from a | ||
419 | signal handler. | ||
420 | This behavior is not supported. | ||
421 | In particular, signal handlers should | ||
422 | .Em not | ||
423 | use any of the | ||
424 | .Fn malloc | ||
425 | functions nor utilize any other functions which may call | ||
426 | .Fn malloc | ||
427 | (e.g., | ||
428 | .Xr stdio 3 | ||
429 | routines). | ||
430 | .It Dq unknown char in MALLOC_OPTIONS | ||
431 | We found something we didn't understand. | ||
432 | .It Dq malloc cache overflow/underflow | ||
433 | The internal malloc page cache has been corrupted. | ||
434 | .It Dq malloc free slot lost | ||
435 | The internal malloc page cache has been corrupted. | ||
436 | .It Dq guard size | ||
437 | An inconsistent guard size was detected. | ||
438 | .It any other error | ||
439 | .Fn malloc | ||
440 | detected an internal error; | ||
441 | consult sources and/or wizards. | ||
442 | .El | ||
443 | .Sh SEE ALSO | 599 | .Sh SEE ALSO |
444 | .Xr brk 2 , | 600 | .Xr brk 2 , |
445 | .Xr mmap 2 , | 601 | .Xr mmap 2 , |
446 | .Xr munmap 2 , | 602 | .Xr munmap 2 , |
447 | .Xr alloca 3 , | 603 | .Xr alloca 3 , |
448 | .Xr getpagesize 3 , | 604 | .Xr getpagesize 3 , |
449 | .Xr posix_memalign 3 | 605 | .Xr posix_memalign 3 , |
606 | .Xr sysconf 3 | ||
450 | .Sh STANDARDS | 607 | .Sh STANDARDS |
451 | The | 608 | The |
452 | .Fn malloc | 609 | .Fn malloc , |
453 | function conforms to | 610 | .Fn calloc , |
611 | .Fn realloc , | ||
612 | and | ||
613 | .Fn free | ||
614 | functions conform to | ||
454 | .St -ansiC . | 615 | .St -ansiC . |
455 | .Sh HISTORY | 616 | .Sh HISTORY |
456 | A | 617 | A |
@@ -496,6 +657,77 @@ random. | |||
496 | A rewrite by Otto Moerbeek introducing a new central data structure and more | 657 | A rewrite by Otto Moerbeek introducing a new central data structure and more |
497 | randomization appeared in | 658 | randomization appeared in |
498 | .Ox 4.4 . | 659 | .Ox 4.4 . |
660 | .Pp | ||
661 | The | ||
499 | .Fn reallocarray | 662 | .Fn reallocarray |
500 | appeared in | 663 | function appeared in |
501 | .Ox 5.6 . | 664 | .Ox 5.6 . |
665 | .Pp | ||
666 | The | ||
667 | .Fn cfree | ||
668 | function appeared in SunOS 4.x. | ||
669 | .Sh CAVEATS | ||
670 | The | ||
671 | .Fn calloc | ||
672 | function checks for integer overflow in | ||
673 | .Ox | ||
674 | and most other modern platforms. | ||
675 | Software targeting ancient platforms should not rely on this behavior. | ||
676 | .Pp | ||
677 | The | ||
678 | .Fn malloc , | ||
679 | .Fn calloc , | ||
680 | and | ||
681 | .Fn realloc | ||
682 | functions have implementation defined behavior when | ||
683 | .Fa size | ||
684 | or | ||
685 | .Fa nmemb | ||
686 | are zero. | ||
687 | .Pp | ||
688 | Allocation of a zero size object returns a pointer to an access protected zero | ||
689 | size object. | ||
690 | Many zero-sized objects can be placed consecutively in shared | ||
691 | protected pages. | ||
692 | The minimum size of the protection on each object is suitably aligned and | ||
693 | sized as previously stated, but the protection may extend further depending | ||
694 | on where in a protected zone the object lands. | ||
695 | Attempting to access these objects will generate a | ||
696 | .Pq Dv SIGSEGV | ||
697 | exception. | ||
698 | .Pp | ||
699 | When using | ||
700 | .Fn malloc , | ||
701 | be wary of signed integer and | ||
702 | .Vt size_t | ||
703 | overflow especially when you | ||
704 | have multiplication in the | ||
705 | .Fa size | ||
706 | argument. | ||
707 | .Pp | ||
708 | Signed integer overflow will cause undefined behavior which compilers | ||
709 | typically handle by wrapping back around to negative numbers. | ||
710 | Depending on the input, this can result in allocating more or less | ||
711 | memory than you intended. | ||
712 | .Pp | ||
713 | An unsigned overflow has defined behavior which will wrap back around and you | ||
714 | will receive less memory than you intended. | ||
715 | .Pp | ||
716 | A signed or unsigned integer overflow is a | ||
717 | .Em security | ||
718 | risk if you end up allocating less memory than you intended. | ||
719 | Your code may corrupt the heap by writing beyond the memory that you | ||
720 | were allocated. | ||
721 | An attacker may be able to leverage this heap corruption to convince your | ||
722 | program to execute arbitrary code. | ||
723 | .Pp | ||
724 | Consider using | ||
725 | .Fn calloc | ||
726 | or | ||
727 | .Fn reallocarray | ||
728 | instead of using multiplication in | ||
729 | .Fn malloc | ||
730 | and | ||
731 | .Fn realloc | ||
732 | to avoid these problems on | ||
733 | .Ox . | ||