| |
@@ -551,6 +551,38 @@
|
| |
realloc(ptr, size);` is wrong because the memory
|
| |
pointed to by `ptr` leaks in case of an error.
|
| |
|
| |
+ ==== Memory leaks
|
| |
+ After a memory area has been allocated with functions like `malloc`,
|
| |
+ `calloc`, etc. and it is no longer necessary, it must be freed in
|
| |
+ order for the system to release the memory region and re-use it if
|
| |
+ necessary. Failing to do so may lead to the application using more
|
| |
+ memory than necessary and, in some cases, crashing due to no more
|
| |
+ memory being available.
|
| |
+
|
| |
+ If portability is not important in your program, an alternative way of
|
| |
+ automatic memory management is to leverage the `cleanup` attribute
|
| |
+ supported by the recent versions of GCC and Clang. If a local variable
|
| |
+ is declared with the attribute, the specified cleanup function will be
|
| |
+ called when the variable goes out of scope.
|
| |
+
|
| |
+ [source,c]
|
| |
+ ----
|
| |
+ static inline void freep(void *p) {
|
| |
+ free(*(void**) p);
|
| |
+ }
|
| |
+
|
| |
+ void somefunction(const char *param) {
|
| |
+ if (strcmp(param, "do_something_complex") == 0) {
|
| |
+ __attribute__((cleanup(freep))) char *ptr = NULL;
|
| |
+
|
| |
+ /* Allocate a temporary buffer */
|
| |
+ ptr = malloc(size);
|
| |
+
|
| |
+ /* Do something on it, but do not need to manually call free() */
|
| |
+ }
|
| |
+ }
|
| |
+ ----
|
| |
+
|
| |
[[sect-Defensive_Coding-C-Use-After-Free]]
|
| |
==== Use-after-free errors
|
| |
|
| |
@@ -632,7 +664,7 @@
|
| |
page size, there is no error checking, either.
|
| |
|
| |
In both cases, negative or very large sizes can trigger a
|
| |
- stack-pointer wraparound, and the stack pointer and end up
|
| |
+ stack-pointer wraparound, and the stack pointer ends up
|
| |
pointing into caller stack frames, which is fatal and can be
|
| |
exploitable.
|
| |
|
| |
@@ -644,30 +676,6 @@
|
| |
function, check if `malloc` had been called,
|
| |
and free the buffer as needed.
|
| |
|
| |
- If portability is not important in your program, an alternative way of
|
| |
- automatic memory management is to leverage the `cleanup` attribute
|
| |
- supported by the recent versions of GCC and Clang. If a local variable
|
| |
- is declared with the attribute, the specified cleanup function will be
|
| |
- called when the variable goes out of scope.
|
| |
-
|
| |
- [source,c]
|
| |
- ----
|
| |
- static inline void freep(void *p) {
|
| |
- free(*(void**) p);
|
| |
- }
|
| |
-
|
| |
- void somefunction(const char *param) {
|
| |
- if (strcmp(param, "do_something_complex") == 0) {
|
| |
- __attribute__((cleanup(freep))) char *ptr = NULL;
|
| |
-
|
| |
- /* Allocate a temporary buffer */
|
| |
- ptr = malloc(size);
|
| |
-
|
| |
- /* Do something on it, but do not need to manually call free() */
|
| |
- }
|
| |
- }
|
| |
- ----
|
| |
-
|
| |
[[sect-Defensive_Coding-C-Allocators-Arrays]]
|
| |
=== Array Allocation
|
| |
|
| |
Reserve a special section for memory leaks and automatic memory management.