Baseline for Ed 2 of tr 24772


Memory Leaks and Heap Fragmentation [XYL]



Yüklə 0,54 Mb.
səhifə25/54
tarix16.08.2018
ölçüsü0,54 Mb.
#63136
1   ...   21   22   23   24   25   26   27   28   ...   54

6.40 Memory Leaks and Heap Fragmentation [XYL]

6.40.1 Description of application vulnerability


A memory leak occurs when software does not release allocated memory after it ceases to be used. Repeated occurrences of a memory leak can consume considerable amounts of available memory. A memory leak can be exploited by attackers to generate denial-of-service by causing the program to execute repeatedly a sequence that triggers the leak. Moreover, a memory leak can cause any long-running critical program to shutdown prematurely.

6.40.2 Cross reference


CWE:

401. Failure to Release Memory Before Removing Last Reference (aka ‘Memory Leak’)

JSF AV Rule: 206

MISRA C 2012: 4.12

CERT C guidelines: MEM00-C and MEM31-C

Ada Quality and Style Guide: 5.4.5, 5.9.2, and 7.3.3


6.40.3 Mechanism of failure


As a process or system runs, any memory taken from dynamic memory and not returned or reclaimed (by the runtime system, the application, or a garbage collector) after it ceases to be used, may result in future memory allocation requests failing for lack of free space.

Alternatively, memory claimed and returned can cause the heap to fragment into progressively smaller blocks, which, with the usual allocators, will result in a higher memory consumption and steadily increasing search times for blocks of suitable size, until the system spends most of the CPU-time for searching the heap for suitable blocks.

Either condition can thus result in a memory exhaustion exception, progressively slower performance by the allocating application, program termination or a system crash.

If an attacker can determine the cause of an existing memory leak or can increase the allocation rate for blocks of different sizes, the attacker will be able to cause the application to leak or fragment quickly and therefore cause the application to crash or fail to perform within acceptable time limits. Denial-of-Service attacks can thus occur.


6.40.4 Applicable language characteristics


This vulnerability description is intended to be applicable to languages with the following characteristics:

  • Languages reclaim memory under programmer control can exhibit heap fragmentation and memory leaks.

  • Languages that support mechanisms to dynamically allocate memory and employ garbage collection can exhibit memory leaks.

6.40.5 Avoiding the vulnerability or mitigating its effects


Software developers can avoid the vulnerability or mitigate its ill effects in the following ways:

  • Use garbage collectors that reclaim memory no longer accessible by the application. Some garbage collectors are part of the language while others are add-ons.

  • In systems with garbage collectors, set all non-local pointers or references to null, when the designated data is no longer needed, since the data transitively reachable from such a pointer or reference will not be garbage-collected otherwise, effectively causing memory leaks.

  • In systems without garbage collectors, cause deallocation of the data before the last pointer or reference to the data is lost.

  • Allocate and free memory at the same level of abstraction, and ideally in the same code module.

Allocating and freeing memory in different modules and levels of abstraction may make it difficult for developers to match requests to free storage with the appropriate storage allocation request. This may cause confusion regarding when and if a block of memory has been allocated or freed, leading to memory leaks.

  • Use Storage pools when available in combination with strong typing. Storage pools are a specialized memory mechanism where all of the memory associated with a class of objects is allocated from a specific bounded region such that storage exhaustion in one pool does not affect the code operating on other memory.

  • Use storage pools of equally-sized blocks to avoid fragmentation within each storage pool. If necessary, provide application-specific (de-)allocators to achieve this functionality.

  • Avoid the use of dynamically allocated storage entirely, or allocate only during system initialization and never allocate once the main execution commences, particularly in safety-critical systems and long running systems.

  • Use static analysis, which can sometimes detect when allocated storage is no longer used and has not been freed.

6.40.6 Implications for standardization


In future standardization activities, the following items should be considered:

  • Languages can provide syntax and semantics to guarantee program-wide that dynamic memory is not used (such as the configuration pragmas feature offered by some programming languages).

  • Languages can document or specify that implementations must document choices for dynamic memory management algorithms, to hope designers decide on appropriate usage patterns and recovery techniques as necessary

6.41 Templates and Generics [SYM]

6.41.1 Description of application vulnerability


Many languages provide a mechanism that allows objects and/or functions to be defined parameterized by type and then instantiated for specific types. In C++ and related languages, these are referred to as “templates”, and in Ada and Java, “generics”. To avoid having to keep writing ‘templates/generics’, in this clause these will simply be referred to collectively as generics.

Used well, generics can make code clearer, more predictable and easier to maintain. Used badly, they can have the reverse effect, making code difficult to review and maintain, leading to the possibility of program error.


6.41.2 Cross reference


JSF AV Rules: 101, 102, 103, 104, and 105

MISRA C++ 2008: 14-6-1, 14-6-2, 14-7-1 to 14-7-3, 14-8-1, and 14-8-2

CERT C++:

Ada Quality and Style Guide: 8.3.1 through 8.3.8, and 8.4.2


6.41.3 Mechanism of failure


The value of generics comes from having a single piece of code that supports some behaviour in a type independent manner. This simplifies development and maintenance of the code. It should also assist in the understanding of the code during review and maintenance, by providing the same behaviour for all types with which it is instantiated.

Problems arise when the use of a generic actually makes the code harder to understand during review and maintenance, by not providing consistent behaviour.

In most cases, the generic definition will have to make assumptions about the types it can legally be instantiated with. For example, a sort function requires that the elements to be sorted can be copied and compared. If these assumptions are not met, the result is likely to be a compiler error. For example if the sort function is instantiated with a user defined type that doesn’t have a relational operator. Where ‘misuse’ of a generic leads to a compiler error, this can be regarded as a development issue, and not a software vulnerability.

Confusion, and hence potential vulnerability, can arise where the instantiated code is apparently invalid, but doesn’t result in a compiler error. For example, a generic class defines a set of members, a subset of which rely on a particular property of the instantiation type (such as a generic container class with a sort member function, only the sort function relies on the instantiating type having a defined relational operator). In some languages, such as C++, if the generic is instantiated with a type that doesn’t meet all the requirements but the program never subsequently makes use of the subset of members that rely on the property of the instantiating type, the code will compile and execute (for example, the generic container is instantiated with a user defined class that doesn’t define a relational operator, but the program never calls the sort member of this instantiation). When the code is reviewed the generic class will appear to reference a member of the instantiating type that doesn’t exist.



The problem as described in the two prior paragraphs can be reduced by a language feature (such as the concepts language feature being designed by the C++ committee). (RESEARCH – AI Erhard.).

Similar confusion can arise if the language permits specific methods of an instance of a generic to be explicitly defined, rather than using the common code, so that behaviour is not consistent for all instantiations. For example, for the same generic container class, the sort member normally sorts the elements of the container into ascending order. In some languages, a ‘special case’ can be created for the instantiation of the generic with a particular type. For example, the sort member for a ‘float’ container may be explicitly defined to provide different behaviour, say sorting the elements into descending order. Specialization that doesn’t affect the apparent behaviour of the instantiation is not an issue.



(C++-specific text, move when appropriate – AI Clive.).Again, for C++, there are some irregularities in the semantics of arrays and pointers that can lead to the generic having different behaviour for different, but apparently very similar, types. In such cases, specialization can be used to enforce consistent behaviour.

6.41.4 Applicable language characteristics


This vulnerability is intended to be applicable to languages with the following characteristics:

  • Languages that permit definitions of objects or functions to be parameterized by type, for later instantiation with specific types, such as:

    • Templates in C++

    • Generics in Ada, Java.

6.41.5 Avoiding the vulnerability or mitigating its effects


Software developers can avoid the vulnerability or mitigate its ill effects in the following ways:

  • Document the properties of an instantiating type necessary for a generic to be valid.

  • If an instantiating type has the required properties, the whole of the generic should be ensured to be valid, whether actually used in the program or not.

  • Preferably avoid, but at least carefully document, any ‘special cases’ where a generic is instantiated with a specific type but doesn’t behave as it does for other types.

6.41.6 Implications for standardization


In future standardization activities, the following items should be considered:

  • Language specifiers should standardize on a common, uniform terminology to describe generics/templates so that programmers experienced in one language can reliably learn and refer to the type system of another language that has the same concept, but with a different name.

  • Language specifiers should design generics in such a way that any attempt to instantiate a generic with constructs that do not provide the required capabilities results in a compile-time error.

  • Language specifiers should provide an assertion mechanism for checking properties at run-time, for those properties that cannot be checked at compile time. It should be possible to inhibit assertion checking if efficiency is a concern.

Yüklə 0,54 Mb.

Dostları ilə paylaş:
1   ...   21   22   23   24   25   26   27   28   ...   54




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©genderi.org 2024
rəhbərliyinə müraciət

    Ana səhifə