diff options
author | cvs2svn <admin@example.com> | 2025-04-14 17:32:06 +0000 |
---|---|---|
committer | cvs2svn <admin@example.com> | 2025-04-14 17:32:06 +0000 |
commit | eb8dd9dca1228af0cd132f515509051ecfabf6f6 (patch) | |
tree | edb6da6af7e865d488dc1a29309f1e1ec226e603 /src/lib/libc/stdlib/malloc.3 | |
parent | 247f0352e0ed72a4f476db9dc91f4d982bc83eb2 (diff) | |
download | openbsd-tb_20250414.tar.gz openbsd-tb_20250414.tar.bz2 openbsd-tb_20250414.zip |
This commit was manufactured by cvs2git to create tag 'tb_20250414'.tb_20250414
Diffstat (limited to 'src/lib/libc/stdlib/malloc.3')
-rw-r--r-- | src/lib/libc/stdlib/malloc.3 | 860 |
1 files changed, 0 insertions, 860 deletions
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3 deleted file mode 100644 index bea5575bf8..0000000000 --- a/src/lib/libc/stdlib/malloc.3 +++ /dev/null | |||
@@ -1,860 +0,0 @@ | |||
1 | .\" | ||
2 | .\" Copyright (c) 1980, 1991, 1993 | ||
3 | .\" The Regents of the University of California. All rights reserved. | ||
4 | .\" | ||
5 | .\" This code is derived from software contributed to Berkeley by | ||
6 | .\" the American National Standards Committee X3, on Information | ||
7 | .\" Processing Systems. | ||
8 | .\" | ||
9 | .\" Redistribution and use in source and binary forms, with or without | ||
10 | .\" modification, are permitted provided that the following conditions | ||
11 | .\" are met: | ||
12 | .\" 1. Redistributions of source code must retain the above copyright | ||
13 | .\" notice, this list of conditions and the following disclaimer. | ||
14 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
15 | .\" notice, this list of conditions and the following disclaimer in the | ||
16 | .\" documentation and/or other materials provided with the distribution. | ||
17 | .\" 3. Neither the name of the University nor the names of its contributors | ||
18 | .\" may be used to endorse or promote products derived from this software | ||
19 | .\" without specific prior written permission. | ||
20 | .\" | ||
21 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
29 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
30 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
31 | .\" SUCH DAMAGE. | ||
32 | .\" | ||
33 | .\" $OpenBSD: malloc.3,v 1.142 2024/08/03 20:09:24 guenther Exp $ | ||
34 | .\" | ||
35 | .Dd $Mdocdate: August 3 2024 $ | ||
36 | .Dt MALLOC 3 | ||
37 | .Os | ||
38 | .Sh NAME | ||
39 | .Nm malloc , | ||
40 | .Nm calloc , | ||
41 | .Nm realloc , | ||
42 | .Nm free , | ||
43 | .Nm reallocarray , | ||
44 | .Nm recallocarray , | ||
45 | .Nm freezero , | ||
46 | .Nm aligned_alloc , | ||
47 | .Nm malloc_conceal , | ||
48 | .Nm calloc_conceal | ||
49 | .Nd memory allocation and deallocation | ||
50 | .Sh SYNOPSIS | ||
51 | .In stdlib.h | ||
52 | .Ft void * | ||
53 | .Fn malloc "size_t size" | ||
54 | .Ft void * | ||
55 | .Fn calloc "size_t nmemb" "size_t size" | ||
56 | .Ft void * | ||
57 | .Fn realloc "void *ptr" "size_t size" | ||
58 | .Ft void | ||
59 | .Fn free "void *ptr" | ||
60 | .Ft void * | ||
61 | .Fn reallocarray "void *ptr" "size_t nmemb" "size_t size" | ||
62 | .Ft void * | ||
63 | .Fn recallocarray "void *ptr" "size_t oldnmemb" "size_t nmemb" "size_t size" | ||
64 | .Ft void | ||
65 | .Fn freezero "void *ptr" "size_t size" | ||
66 | .Ft void * | ||
67 | .Fn aligned_alloc "size_t alignment" "size_t size" | ||
68 | .Ft void * | ||
69 | .Fn malloc_conceal "size_t size" | ||
70 | .Ft void * | ||
71 | .Fn calloc_conceal "size_t nmemb" "size_t size" | ||
72 | .Vt char *malloc_options ; | ||
73 | .Sh DESCRIPTION | ||
74 | The standard functions | ||
75 | .Fn malloc , | ||
76 | .Fn calloc , | ||
77 | and | ||
78 | .Fn realloc | ||
79 | allocate | ||
80 | .Em objects , | ||
81 | regions of memory to store values. | ||
82 | The | ||
83 | .Fn malloc | ||
84 | function allocates uninitialized space for an object of | ||
85 | the specified | ||
86 | .Fa size . | ||
87 | .Fn malloc | ||
88 | maintains multiple lists of free objects according to size, allocating | ||
89 | from the appropriate list or requesting memory from the kernel. | ||
90 | The allocated space is suitably aligned (after possible pointer coercion) for | ||
91 | storage of any type of object. | ||
92 | .Pp | ||
93 | The | ||
94 | .Fn calloc | ||
95 | function allocates space for an array of | ||
96 | .Fa nmemb | ||
97 | objects, each of the specified | ||
98 | .Fa size . | ||
99 | The space is initialized to zero. | ||
100 | .Pp | ||
101 | The | ||
102 | .Fn realloc | ||
103 | function changes the size of the object pointed to by | ||
104 | .Fa ptr | ||
105 | to | ||
106 | .Fa size | ||
107 | bytes and returns a pointer to the (possibly moved) object. | ||
108 | If | ||
109 | .Fa ptr | ||
110 | is not | ||
111 | .Dv NULL , | ||
112 | it must be a pointer returned by an earlier call to an allocation or | ||
113 | reallocation function that was not freed in between. | ||
114 | The contents of the object are unchanged up to the lesser | ||
115 | of the new and old sizes. | ||
116 | If the new size is larger, the value of the newly allocated portion | ||
117 | of the object is indeterminate and uninitialized. | ||
118 | If the space cannot be allocated, the object | ||
119 | pointed to by | ||
120 | .Fa ptr | ||
121 | is unchanged. | ||
122 | If | ||
123 | .Fa ptr | ||
124 | is | ||
125 | .Dv NULL , | ||
126 | .Fn realloc | ||
127 | behaves like | ||
128 | .Fn malloc | ||
129 | and allocates a new object. | ||
130 | .Pp | ||
131 | The | ||
132 | .Fn free | ||
133 | function causes the space pointed to by | ||
134 | .Fa ptr | ||
135 | to be either placed on a list of free blocks to make it available for future | ||
136 | allocation or, when appropriate, to be returned to the kernel using | ||
137 | .Xr munmap 2 . | ||
138 | If | ||
139 | .Fa ptr | ||
140 | is | ||
141 | .Dv NULL , | ||
142 | no action occurs. | ||
143 | If | ||
144 | .Fa ptr | ||
145 | was previously freed by | ||
146 | .Fn free | ||
147 | or a reallocation function, | ||
148 | the behavior is undefined and the double free is a security concern. | ||
149 | .Pp | ||
150 | Designed for safe allocation of arrays, | ||
151 | the | ||
152 | .Fn reallocarray | ||
153 | function is similar to | ||
154 | .Fn realloc | ||
155 | except it operates on | ||
156 | .Fa nmemb | ||
157 | members of size | ||
158 | .Fa size | ||
159 | and checks for integer overflow in the calculation | ||
160 | .Fa nmemb | ||
161 | * | ||
162 | .Fa size . | ||
163 | .Pp | ||
164 | Used for the allocation of memory holding sensitive data, | ||
165 | the | ||
166 | .Fn recallocarray | ||
167 | and | ||
168 | .Fn freezero | ||
169 | functions guarantee that memory becoming unallocated is explicitly | ||
170 | .Em discarded , | ||
171 | meaning pages of memory are disposed via | ||
172 | .Xr munmap 2 | ||
173 | and cached free objects are cleared with | ||
174 | .Xr explicit_bzero 3 . | ||
175 | .Pp | ||
176 | The | ||
177 | .Fn recallocarray | ||
178 | function is similar to | ||
179 | .Fn reallocarray | ||
180 | except it ensures newly allocated memory is cleared similar to | ||
181 | .Fn calloc . | ||
182 | If | ||
183 | .Fa ptr | ||
184 | is | ||
185 | .Dv NULL , | ||
186 | .Fa oldnmemb | ||
187 | is ignored and the call is equivalent to | ||
188 | .Fn calloc . | ||
189 | If | ||
190 | .Fa ptr | ||
191 | is not | ||
192 | .Dv NULL , | ||
193 | .Fa oldnmemb | ||
194 | must be a value such that | ||
195 | .Fa oldnmemb | ||
196 | * | ||
197 | .Fa size | ||
198 | is the size of the earlier allocation that returned | ||
199 | .Fa ptr , | ||
200 | otherwise the behavior is undefined. | ||
201 | .Pp | ||
202 | The | ||
203 | .Fn freezero | ||
204 | function is similar to the | ||
205 | .Fn free | ||
206 | function except it ensures memory is explicitly discarded. | ||
207 | If | ||
208 | .Fa ptr | ||
209 | is | ||
210 | .Dv NULL , | ||
211 | no action occurs. | ||
212 | If | ||
213 | .Fa ptr | ||
214 | is not | ||
215 | .Dv NULL , | ||
216 | the | ||
217 | .Fa size | ||
218 | argument must be equal to or smaller than the size of the earlier allocation | ||
219 | that returned | ||
220 | .Fa ptr . | ||
221 | .Fn freezero | ||
222 | guarantees the memory range starting at | ||
223 | .Fa ptr | ||
224 | with length | ||
225 | .Fa size | ||
226 | is discarded while deallocating the whole object originally allocated. | ||
227 | .Pp | ||
228 | The | ||
229 | .Fn aligned_alloc | ||
230 | function allocates | ||
231 | .Fa size | ||
232 | bytes of memory such that the allocation's base address is a multiple of | ||
233 | .Fa alignment . | ||
234 | The requested | ||
235 | .Fa alignment | ||
236 | must be a power of 2. | ||
237 | If | ||
238 | .Fa size | ||
239 | is not a multiple of | ||
240 | .Fa alignment , | ||
241 | behavior is undefined. | ||
242 | .Pp | ||
243 | The | ||
244 | .Fn malloc_conceal | ||
245 | and | ||
246 | .Fn calloc_conceal | ||
247 | functions behave the same as | ||
248 | .Fn malloc | ||
249 | and | ||
250 | .Fn calloc | ||
251 | respectively, | ||
252 | with the exception that the allocation returned is marked with the | ||
253 | .Dv MAP_CONCEAL | ||
254 | .Xr mmap 2 | ||
255 | flag and calling | ||
256 | .Fn free | ||
257 | on the allocation will discard the contents explicitly. | ||
258 | A reallocation of a concealed allocation will leave these properties intact. | ||
259 | .Sh MALLOC OPTIONS | ||
260 | Upon the first call to the | ||
261 | .Fn malloc | ||
262 | family of functions, an initialization sequence inspects the | ||
263 | value of the | ||
264 | .Va vm.malloc_conf | ||
265 | .Xr sysctl 2 , | ||
266 | next checks the environment for a variable called | ||
267 | .Ev MALLOC_OPTIONS , | ||
268 | and finally looks at the global variable | ||
269 | .Va malloc_options | ||
270 | in the program. | ||
271 | Each is scanned for the flags documented below. | ||
272 | Unless otherwise noted uppercase means on, lowercase means off. | ||
273 | During initialization, flags occurring later modify the behaviour | ||
274 | that was requested by flags processed earlier. | ||
275 | .Bl -tag -width indent | ||
276 | .It Cm C | ||
277 | .Dq Canaries . | ||
278 | Add canaries at the end of allocations in order to detect | ||
279 | heap overflows. | ||
280 | The canary's content is checked when | ||
281 | .Nm free | ||
282 | is called. | ||
283 | If it has been corrupted, the process is aborted. | ||
284 | .It Cm D | ||
285 | .Dq Dump . | ||
286 | .Fn malloc | ||
287 | will dump a leak report using | ||
288 | .Xr utrace 2 | ||
289 | at exit. | ||
290 | To record the dump: | ||
291 | .Pp | ||
292 | .Dl $ MALLOC_OPTIONS=D ktrace -tu program ... | ||
293 | .Pp | ||
294 | To view the leak report: | ||
295 | .Pp | ||
296 | .Dl $ kdump -u malloc ... | ||
297 | .Pp | ||
298 | By default, the immediate caller of a | ||
299 | .Nm | ||
300 | function will be recorded. | ||
301 | Use malloc option | ||
302 | .Cm 2 , | ||
303 | .Cm 3 | ||
304 | or | ||
305 | .Cm 4 | ||
306 | to record deeper call stacks. | ||
307 | These malloc options imply | ||
308 | .Cm D . | ||
309 | .It Cm F | ||
310 | .Dq Freecheck . | ||
311 | Enable more extensive double free and write after free detection. | ||
312 | All chunks in the delayed free list will be checked for double frees and | ||
313 | write after frees. | ||
314 | Unused pages on the freelist are read and write protected to | ||
315 | cause a segmentation fault upon access. | ||
316 | .It Cm G | ||
317 | .Dq Guard . | ||
318 | Enable guard pages. | ||
319 | Each page size or larger allocation is followed by a guard page that will | ||
320 | cause a segmentation fault upon any access. | ||
321 | .It Cm J | ||
322 | .Dq More junking . | ||
323 | Increase the junk level by one if it is smaller than 2. | ||
324 | .It Cm j | ||
325 | .Dq Less junking . | ||
326 | Decrease the junk level by one if it is larger than 0. | ||
327 | Junking writes some junk bytes into the area allocated. | ||
328 | Junk is bytes of 0xdb when allocating; | ||
329 | small allocations are initially junked with 0xdf as are freed allocations. | ||
330 | By default the junk level is 1: after free, | ||
331 | small chunks are completely junked; | ||
332 | for pages the first part is junked. | ||
333 | After a delay, | ||
334 | the filling pattern is validated and the process is aborted if the pattern | ||
335 | was modified. | ||
336 | For junk level 2, junking is done on allocation as well and without size | ||
337 | restrictions. | ||
338 | If the junk level is zero, no junking is performed. | ||
339 | .It Cm R | ||
340 | .Dq realloc . | ||
341 | Always reallocate when | ||
342 | .Fn realloc | ||
343 | is called, even if the initial allocation was big enough. | ||
344 | .\".Pp | ||
345 | .\".It Cm U | ||
346 | .\".Dq utrace . | ||
347 | .\"Generate entries for | ||
348 | .\".Xr ktrace 1 | ||
349 | .\"for all operations. | ||
350 | .\"Consult the source for this one. | ||
351 | .It Cm S | ||
352 | .\" Malloc option S is vaguely documented on purpose. | ||
353 | Enable all options suitable for security auditing. | ||
354 | .It Cm U | ||
355 | .Dq Free unmap . | ||
356 | Enable use after free protection for larger allocations. | ||
357 | Unused pages on the freelist are read and write protected to | ||
358 | cause a segmentation fault upon access. | ||
359 | .It Cm V | ||
360 | .Dq Verbose . | ||
361 | Use with | ||
362 | .Cm D | ||
363 | to get a verbose dump of malloc's internal state. | ||
364 | .It Cm X | ||
365 | .Dq xmalloc . | ||
366 | Rather than return failure, | ||
367 | .Xr abort 3 | ||
368 | the program with a diagnostic message on stderr. | ||
369 | It is the intention that this option be set at compile time by | ||
370 | including in the source: | ||
371 | .Bd -literal -offset indent | ||
372 | extern char *malloc_options; | ||
373 | malloc_options = "X"; | ||
374 | .Ed | ||
375 | .Pp | ||
376 | Note that this will cause code that is supposed to handle | ||
377 | out-of-memory conditions gracefully to abort instead. | ||
378 | .It Cm < | ||
379 | .Dq Halve the cache size . | ||
380 | Decrease the size of the free page cache by a factor of two. | ||
381 | .It Cm > | ||
382 | .Dq Double the cache size . | ||
383 | Increase the size of the free page cache by a factor of two. | ||
384 | .El | ||
385 | .Pp | ||
386 | If a program changes behavior if any of these options (except | ||
387 | .Cm X ) | ||
388 | are used, | ||
389 | it is buggy. | ||
390 | .Pp | ||
391 | The default size of the cache is 64 single page allocations. | ||
392 | It also caches a number of larger regions. | ||
393 | Multi-threaded programs use multiple pools. | ||
394 | .Sh RETURN VALUES | ||
395 | Upon successful completion, the allocation functions | ||
396 | return a pointer to the allocated space; otherwise, | ||
397 | .Dv NULL | ||
398 | is returned and | ||
399 | .Va errno | ||
400 | is set to | ||
401 | .Er ENOMEM . | ||
402 | The function | ||
403 | .Fn aligned_alloc | ||
404 | returns | ||
405 | .Dv NULL | ||
406 | and sets | ||
407 | .Va errno | ||
408 | to | ||
409 | .Er EINVAL | ||
410 | if | ||
411 | .Fa alignment | ||
412 | is not a power of 2. | ||
413 | .Pp | ||
414 | If | ||
415 | .Fa nmemb | ||
416 | or | ||
417 | .Fa size | ||
418 | is equal to 0, a unique pointer to an access protected, | ||
419 | zero sized object is returned. | ||
420 | Access via this pointer will generate a | ||
421 | .Dv SIGSEGV | ||
422 | exception. | ||
423 | .Pp | ||
424 | If multiplying | ||
425 | .Fa nmemb | ||
426 | and | ||
427 | .Fa size | ||
428 | results in integer overflow, | ||
429 | .Fn calloc , | ||
430 | .Fn reallocarray | ||
431 | and | ||
432 | .Fn recallocarray | ||
433 | return | ||
434 | .Dv NULL | ||
435 | and set | ||
436 | .Va errno | ||
437 | to | ||
438 | .Er ENOMEM . | ||
439 | .Pp | ||
440 | If | ||
441 | .Fa ptr | ||
442 | is not | ||
443 | .Dv NULL | ||
444 | and multiplying | ||
445 | .Fa oldnmemb | ||
446 | and | ||
447 | .Fa size | ||
448 | results in integer overflow, | ||
449 | .Fn recallocarray | ||
450 | returns | ||
451 | .Dv NULL | ||
452 | and sets | ||
453 | .Va errno | ||
454 | to | ||
455 | .Er EINVAL . | ||
456 | .Sh IDIOMS | ||
457 | Consider | ||
458 | .Fn calloc | ||
459 | or the extensions | ||
460 | .Fn reallocarray | ||
461 | and | ||
462 | .Fn recallocarray | ||
463 | when there is multiplication in the | ||
464 | .Fa size | ||
465 | argument of | ||
466 | .Fn malloc | ||
467 | or | ||
468 | .Fn realloc . | ||
469 | For example, avoid this common idiom as it may lead to integer overflow: | ||
470 | .Bd -literal -offset indent | ||
471 | if ((p = malloc(num * size)) == NULL) | ||
472 | err(1, NULL); | ||
473 | .Ed | ||
474 | .Pp | ||
475 | A drop-in replacement is the | ||
476 | .Ox | ||
477 | extension | ||
478 | .Fn reallocarray : | ||
479 | .Bd -literal -offset indent | ||
480 | if ((p = reallocarray(NULL, num, size)) == NULL) | ||
481 | err(1, NULL); | ||
482 | .Ed | ||
483 | .Pp | ||
484 | Alternatively, | ||
485 | .Fn calloc | ||
486 | may be used at the cost of initialization overhead. | ||
487 | .Pp | ||
488 | When using | ||
489 | .Fn realloc , | ||
490 | be careful to avoid the following idiom: | ||
491 | .Bd -literal -offset indent | ||
492 | size += 50; | ||
493 | if ((p = realloc(p, size)) == NULL) | ||
494 | return (NULL); | ||
495 | .Ed | ||
496 | .Pp | ||
497 | Do not adjust the variable describing how much memory has been allocated | ||
498 | until the allocation has been successful. | ||
499 | This can cause aberrant program behavior if the incorrect size value is used. | ||
500 | In most cases, the above sample will also result in a leak of memory. | ||
501 | As stated earlier, a return value of | ||
502 | .Dv NULL | ||
503 | indicates that the old object still remains allocated. | ||
504 | Better code looks like this: | ||
505 | .Bd -literal -offset indent | ||
506 | newsize = size + 50; | ||
507 | if ((newp = realloc(p, newsize)) == NULL) { | ||
508 | free(p); | ||
509 | p = NULL; | ||
510 | size = 0; | ||
511 | return (NULL); | ||
512 | } | ||
513 | p = newp; | ||
514 | size = newsize; | ||
515 | .Ed | ||
516 | .Pp | ||
517 | As with | ||
518 | .Fn malloc , | ||
519 | it is important to ensure the new size value will not overflow; | ||
520 | i.e. avoid allocations like the following: | ||
521 | .Bd -literal -offset indent | ||
522 | if ((newp = realloc(p, num * size)) == NULL) { | ||
523 | ... | ||
524 | .Ed | ||
525 | .Pp | ||
526 | Instead, use | ||
527 | .Fn reallocarray : | ||
528 | .Bd -literal -offset indent | ||
529 | if ((newp = reallocarray(p, num, size)) == NULL) { | ||
530 | ... | ||
531 | .Ed | ||
532 | .Pp | ||
533 | Calling | ||
534 | .Fn realloc | ||
535 | with a | ||
536 | .Dv NULL | ||
537 | .Fa ptr | ||
538 | is equivalent to calling | ||
539 | .Fn malloc . | ||
540 | Instead of this idiom: | ||
541 | .Bd -literal -offset indent | ||
542 | if (p == NULL) | ||
543 | newp = malloc(newsize); | ||
544 | else | ||
545 | newp = realloc(p, newsize); | ||
546 | .Ed | ||
547 | .Pp | ||
548 | Use the following: | ||
549 | .Bd -literal -offset indent | ||
550 | newp = realloc(p, newsize); | ||
551 | .Ed | ||
552 | .Pp | ||
553 | The | ||
554 | .Fn recallocarray | ||
555 | function should be used for resizing objects containing sensitive data like | ||
556 | keys. | ||
557 | To avoid leaking information, | ||
558 | it guarantees memory is cleared before placing it on the internal free list. | ||
559 | Deallocation of such an object should be done by calling | ||
560 | .Fn freezero . | ||
561 | .Sh ENVIRONMENT | ||
562 | .Bl -tag -width "MALLOC_OPTIONS" | ||
563 | .It Ev MALLOC_OPTIONS | ||
564 | String of option flags. | ||
565 | .El | ||
566 | .Sh EXAMPLES | ||
567 | If | ||
568 | .Fn malloc | ||
569 | must be used with multiplication, be sure to test for overflow: | ||
570 | .Bd -literal -offset indent | ||
571 | size_t num, size; | ||
572 | \&... | ||
573 | |||
574 | /* Check for size_t overflow */ | ||
575 | if (size && num > SIZE_MAX / size) | ||
576 | errc(1, EOVERFLOW, "overflow"); | ||
577 | |||
578 | if ((p = malloc(num * size)) == NULL) | ||
579 | err(1, NULL); | ||
580 | .Ed | ||
581 | .Pp | ||
582 | The above test is not sufficient in all cases. | ||
583 | For example, multiplying ints requires a different set of checks: | ||
584 | .Bd -literal -offset indent | ||
585 | int num, size; | ||
586 | \&... | ||
587 | |||
588 | /* Avoid invalid requests */ | ||
589 | if (size < 0 || num < 0) | ||
590 | errc(1, EOVERFLOW, "overflow"); | ||
591 | |||
592 | /* Check for signed int overflow */ | ||
593 | if (size && num > INT_MAX / size) | ||
594 | errc(1, EOVERFLOW, "overflow"); | ||
595 | |||
596 | if ((p = malloc(num * size)) == NULL) | ||
597 | err(1, NULL); | ||
598 | .Ed | ||
599 | .Pp | ||
600 | Assuming the implementation checks for integer overflow as | ||
601 | .Ox | ||
602 | does, it is much easier to use | ||
603 | .Fn calloc , | ||
604 | .Fn reallocarray , | ||
605 | or | ||
606 | .Fn recallocarray . | ||
607 | .Pp | ||
608 | The above examples could be simplified to: | ||
609 | .Bd -literal -offset indent | ||
610 | if ((p = reallocarray(NULL, num, size)) == NULL) | ||
611 | err(1, NULL); | ||
612 | .Ed | ||
613 | .Pp | ||
614 | or at the cost of initialization: | ||
615 | .Bd -literal -offset indent | ||
616 | if ((p = calloc(num, size)) == NULL) | ||
617 | err(1, NULL); | ||
618 | .Ed | ||
619 | .Pp | ||
620 | Set a systemwide reduction of the cache to a quarter of the | ||
621 | default size and use guard pages: | ||
622 | .Pp | ||
623 | .Dl # sysctl vm.malloc_conf='G<<' | ||
624 | .Sh DIAGNOSTICS | ||
625 | If any of the functions detect an error condition, | ||
626 | a message will be printed to file descriptor | ||
627 | 2 (not using stdio). | ||
628 | Errors will result in the process being aborted. | ||
629 | .Pp | ||
630 | Here is a brief description of the error messages and what they mean: | ||
631 | .Bl -tag -width Ds | ||
632 | .It Dq out of memory | ||
633 | If the | ||
634 | .Cm X | ||
635 | option is specified, it is an error for the allocation functions | ||
636 | to return | ||
637 | .Dv NULL . | ||
638 | .It Dq bogus pointer (double free?) | ||
639 | An attempt to | ||
640 | .Fn free | ||
641 | or | ||
642 | reallocate an unallocated pointer was made. | ||
643 | .It Dq double free | ||
644 | There was an attempt to free an allocation that had already been freed. | ||
645 | .It Dq write to free mem Va address Ns [ Va start Ns .. Ns Va end Ns ]@ Ns Va size | ||
646 | An allocation has been modified after it was freed, | ||
647 | or a chunk that was never allocated was written to. | ||
648 | The | ||
649 | .Va range | ||
650 | at which corruption was detected is printed between [ and ]. | ||
651 | .Pp | ||
652 | Enabling option | ||
653 | .Cm D | ||
654 | allows malloc to print information about where the allocation | ||
655 | was done. | ||
656 | .It Dq modified chunk-pointer | ||
657 | The pointer passed to | ||
658 | .Fn free | ||
659 | or a reallocation function has been modified. | ||
660 | .It Dq canary corrupted Va address Ns [ Va offset Ns ]@ Ns Va length Ns / Ns Va size | ||
661 | A byte after the requested | ||
662 | .Va length | ||
663 | has been overwritten, | ||
664 | indicating a heap overflow. | ||
665 | The | ||
666 | .Va offset | ||
667 | at which corruption was detected is printed between [ and ], | ||
668 | the requested | ||
669 | .Va length | ||
670 | of the allocation is printed before the / and the | ||
671 | .Va size | ||
672 | of the allocation after the /. | ||
673 | .It Dq recorded size Va oldsize No inconsistent with Va size | ||
674 | .Fn recallocarray | ||
675 | or | ||
676 | .Fn freezero | ||
677 | has detected that the given old size does not match the recorded size in its | ||
678 | meta data. | ||
679 | Enabling option | ||
680 | .Cm C | ||
681 | allows | ||
682 | .Fn recallocarray | ||
683 | to catch more of these cases. | ||
684 | .It Dq recursive call | ||
685 | An attempt was made to call recursively into these functions, i.e., from a | ||
686 | signal handler. | ||
687 | This behavior is not supported. | ||
688 | In particular, signal handlers should | ||
689 | .Em not | ||
690 | use any of the | ||
691 | .Fn malloc | ||
692 | functions nor utilize any other functions which may call | ||
693 | .Fn malloc | ||
694 | (e.g., | ||
695 | .Xr stdio 3 | ||
696 | routines). | ||
697 | .It Dq unknown char in Ev MALLOC_OPTIONS | ||
698 | We found something we didn't understand. | ||
699 | .It any other error | ||
700 | .Fn malloc | ||
701 | detected an internal error; | ||
702 | consult sources and/or wizards. | ||
703 | .El | ||
704 | .Sh SEE ALSO | ||
705 | .Xr brk 2 , | ||
706 | .Xr mmap 2 , | ||
707 | .Xr munmap 2 , | ||
708 | .Xr sysctl 2 , | ||
709 | .Xr alloca 3 , | ||
710 | .Xr getpagesize 3 , | ||
711 | .Xr posix_memalign 3 | ||
712 | .Sh STANDARDS | ||
713 | The | ||
714 | .Fn malloc , | ||
715 | .Fn calloc , | ||
716 | .Fn realloc , | ||
717 | and | ||
718 | .Fn free | ||
719 | functions conform to | ||
720 | .St -ansiC . | ||
721 | The | ||
722 | .Fn aligned_alloc | ||
723 | function conforms to | ||
724 | .St -isoC-2011 . | ||
725 | The | ||
726 | .Fn reallocarray | ||
727 | function conforms to | ||
728 | .St -p1003.1-2024 . | ||
729 | .Pp | ||
730 | If | ||
731 | .Fa nmemb | ||
732 | or | ||
733 | .Fa size | ||
734 | are 0, the return value is implementation defined; | ||
735 | other conforming implementations may return | ||
736 | .Dv NULL | ||
737 | in this case. | ||
738 | .Pp | ||
739 | The | ||
740 | .Ev MALLOC_OPTIONS | ||
741 | environment variable, the | ||
742 | .Va vm.malloc_conf | ||
743 | sysctl and the | ||
744 | .Sx DIAGNOSTICS | ||
745 | output are extensions to the standard. | ||
746 | .Sh HISTORY | ||
747 | A | ||
748 | .Fn free | ||
749 | internal kernel function and a predecessor to | ||
750 | .Fn malloc , | ||
751 | .Fn alloc , | ||
752 | first appeared in | ||
753 | .At v1 . | ||
754 | C library functions | ||
755 | .Fn alloc | ||
756 | and | ||
757 | .Fn free | ||
758 | appeared in | ||
759 | .At v6 . | ||
760 | The functions | ||
761 | .Fn malloc , | ||
762 | .Fn calloc , | ||
763 | and | ||
764 | .Fn realloc | ||
765 | first appeared in | ||
766 | .At v7 . | ||
767 | .Pp | ||
768 | A new implementation by Chris Kingsley was introduced in | ||
769 | .Bx 4.2 , | ||
770 | followed by a complete rewrite by Poul-Henning Kamp which appeared in | ||
771 | .Fx 2.2 | ||
772 | and was included in | ||
773 | .Ox 2.0 . | ||
774 | These implementations were all | ||
775 | .Xr sbrk 2 | ||
776 | based. | ||
777 | In | ||
778 | .Ox 3.8 , | ||
779 | Thierry Deval rewrote | ||
780 | .Nm | ||
781 | to use the | ||
782 | .Xr mmap 2 | ||
783 | system call, | ||
784 | making the page addresses returned by | ||
785 | .Nm | ||
786 | random. | ||
787 | A rewrite by Otto Moerbeek introducing a new central data structure and more | ||
788 | randomization appeared in | ||
789 | .Ox 4.4 . | ||
790 | .Pp | ||
791 | The | ||
792 | .Fn reallocarray | ||
793 | function appeared in | ||
794 | .Ox 5.6 . | ||
795 | The | ||
796 | .Fn recallocarray | ||
797 | function appeared in | ||
798 | .Ox 6.1 . | ||
799 | The | ||
800 | .Fn freezero | ||
801 | function appeared in | ||
802 | .Ox 6.2 . | ||
803 | The | ||
804 | .Fn aligned_alloc | ||
805 | function appeared in | ||
806 | .Ox 6.5 . | ||
807 | The | ||
808 | .Fn malloc_conceal | ||
809 | and | ||
810 | .Fn calloc_conceal | ||
811 | functions appeared in | ||
812 | .Ox 6.6 . | ||
813 | .Sh CAVEATS | ||
814 | When using | ||
815 | .Fn malloc , | ||
816 | be wary of signed integer and | ||
817 | .Vt size_t | ||
818 | overflow especially when there is multiplication in the | ||
819 | .Fa size | ||
820 | argument. | ||
821 | .Pp | ||
822 | Signed integer overflow will cause undefined behavior which compilers | ||
823 | typically handle by wrapping back around to negative numbers. | ||
824 | Depending on the input, this can result in allocating more or less | ||
825 | memory than intended. | ||
826 | .Pp | ||
827 | An unsigned overflow has defined behavior which will wrap back around and | ||
828 | return less memory than intended. | ||
829 | .Pp | ||
830 | A signed or unsigned integer overflow is a | ||
831 | .Em security | ||
832 | risk if less memory is returned than intended. | ||
833 | Subsequent code may corrupt the heap by writing beyond the memory that was | ||
834 | allocated. | ||
835 | An attacker may be able to leverage this heap corruption to execute arbitrary | ||
836 | code. | ||
837 | .Pp | ||
838 | Consider using | ||
839 | .Fn calloc , | ||
840 | .Fn reallocarray | ||
841 | or | ||
842 | .Fn recallocarray | ||
843 | instead of using multiplication in | ||
844 | .Fn malloc | ||
845 | and | ||
846 | .Fn realloc | ||
847 | to avoid these problems on | ||
848 | .Ox . | ||
849 | .Pp | ||
850 | The mechanism to record caller functions when using malloc options | ||
851 | .Cm 2 , | ||
852 | .Cm 3 , | ||
853 | or | ||
854 | .Cm 4 | ||
855 | is not guaranteed to work for all platforms, compilers or compilation | ||
856 | options, | ||
857 | and might even crash your program. | ||
858 | Use | ||
859 | .Em only | ||
860 | for debugging purposes. | ||