diff options
Diffstat (limited to 'src/lib/libc/stdlib')
| -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 . | ||
