|
| 1 | +<!DOCTYPE qhelp PUBLIC |
| 2 | + "-//Semmle//qhelp//EN" |
| 3 | + "qhelp.dtd"> |
| 4 | +<qhelp> |
| 5 | +<overview> |
| 6 | +<p> |
| 7 | +Using an object after its lifetime has ended results in undefined behavior. |
| 8 | +When an object's lifetime has ended it relinquishes ownership of its resources and the memory it occupied may be reused for other purposes. |
| 9 | +If the object is accessed after its lifetime has ended, the program may crash or behave in unexpected ways. |
| 10 | +</p> |
| 11 | + |
| 12 | +</overview> |
| 13 | +<recommendation> |
| 14 | + |
| 15 | +<p> |
| 16 | +Ensure that no object is accessed after its lifetime has ended. |
| 17 | +Use RAII ("Resource Acquisition Is Initialization") to manage the lifetime of objects, and avoid manual memory management, if possible. |
| 18 | +</p> |
| 19 | + |
| 20 | +</recommendation> |
| 21 | +<example> |
| 22 | +<p> |
| 23 | +The following two examples demonstrate common lifetime violations when working with the C++ standard library. |
| 24 | +</p> |
| 25 | + |
| 26 | +<p> |
| 27 | +The <code>bad_call_c_api</code> function contains a use of an expired lifetime. |
| 28 | +First, a temporary object of type <code>std::string</code> is constructed, and a pointer to its internal buffer is stored in a local variable. |
| 29 | +Once the <code>c_str()</code> call returns, the temporary object is destroyed, and the memory pointed to by <code>p</code> is freed. |
| 30 | +Thus, any attempt to dereference <code>p</code> inside <code>c_api</code> will result in a use-after-free vulnerability. |
| 31 | + |
| 32 | +The <code>good_call_c_api</code> function contains a fixed version of the first example. |
| 33 | +The variable <code>hello</code> is declared as a local variable, and the pointer to its internal buffer is stored in <code>p</code>. |
| 34 | +The lifetime of hello outlives the call to <code>c_api</code>, so the pointer stored in <code>p</code> remains valid throughout the call to <code>c_api</code>. |
| 35 | +</p> |
| 36 | +<sample src="UseAfterExpiredLifetime_c_api_call.cpp" /> |
| 37 | + |
| 38 | +<p> |
| 39 | +The <code>bad_remove_even_numbers</code> function demonstrates a potential issue with iterator invalidation. |
| 40 | +Each C++ standard library container comes with a specification of which operations invalidates iterators pointing into the container. |
| 41 | +For example, calling <code>erase</code> on an object of type <code>std::vector<T></code> invalidates all its iterators, and thus any attempt to dereference the iterator can result in a use-after-free vulnerability. |
| 42 | + |
| 43 | +The <code>good_remove_even_numbers</code> function contains a fixd version of the third example. |
| 44 | +The <code>erase</code> function returns an iterator to the element following the last element removed, and this return value is used to ensure that <code>it</code> remains valid after the call to <code>erase</code>. |
| 45 | +</p> |
| 46 | +<sample src="UseAfterExpiredLifetime_iterator_invalidation.cpp" /> |
| 47 | + |
| 48 | +</example> |
| 49 | +<references> |
| 50 | + |
| 51 | +<li>CERT C Coding Standard: |
| 52 | +<a href="https://wiki.sei.cmu.edu/confluence/display/c/MEM30-C.+Do+not+access+freed+memory">MEM30-C. Do not access freed memory</a>.</li> |
| 53 | +<li> |
| 54 | +OWASP: |
| 55 | +<a href="https://owasp.org/www-community/vulnerabilities/Using_freed_memory">Using freed memory</a>. |
| 56 | +</li> |
| 57 | +<li> |
| 58 | +<a href="https://github.com/isocpp/CppCoreGuidelines/blob/master/docs/Lifetime.pdf">Lifetime safety: Preventing common dangling</a> |
| 59 | +</li> |
| 60 | +<li> |
| 61 | +<a href="https://en.cppreference.com/w/cpp/container">Containers library</a> |
| 62 | +</li> |
| 63 | +<li> |
| 64 | +<a href="https://en.cppreference.com/w/cpp/language/raii">RAII</a> |
| 65 | +</li> |
| 66 | + |
| 67 | +</references> |
| 68 | +</qhelp> |
0 commit comments