Baseline for Ed 2 of tr 24772



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

6.35 Recursion [GDL]

6.35.1 Description of application vulnerability


Recursion is an elegant mathematical mechanism for defining the values of some functions. It is tempting to write code that mirrors the mathematics. However, the use of recursion in a computer can have a profound effect on the consumption of finite resources, leading to denial of service.

6.35.2 Cross reference


CWE:

674. Uncontrolled Recursion

JSF AV Rule: 119

MISRA C 2012: 17.2

MISRA C++ 2008: 7-5-4

CERT C guidelines: MEM05-C

Ada Quality and Style Guide: 5.6.6

6.35.3 Mechanism of failure


Recursion provides for the economical definition of some mathematical functions. However, economical definition and economical calculation are two different subjects. It is tempting to calculate the value of a recursive function using recursive subprograms because the expression in the programming language is straightforward and easy to understand. However, the impact on finite computing resources can be profound. Each invocation of a recursive subprogram may result in the creation of a new stack frame, complete with local variables. If stack space is limited and the calculation of some values will lead to an exhaustion of resources resulting in the program terminating.

In calculating the values of mathematical functions the use of recursion in a program is usually obvious, but this is not true when considering computer operations generally, especially when processing error conditions. For example, finalization of a computing context after treating an error condition might result in recursion (such as attempting to recover resources by closing a file after an error was encountered in closing the same file). Although such situations may have other problems, they typically do not result in exhaustion of resources but may otherwise result in a denial of service.


6.35.4 Applicable language characteristics


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

  • Any language that permits the recursive invocation of subprograms.

6.35.5 Avoiding the vulnerability or mitigating its effects


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

  • Minimize the use of recursion.

  • Converting recursive calculations to the corresponding iterative calculation. In principle, any recursive calculation can be remodeled as an iterative calculation which will have a smaller impact on some computing resources but which may be harder for a human to comprehend. The cost to human understanding must be weighed against the practical limits of computing resource.

  • In cases where the depth of recursion can be shown to be statically bounded by a tolerable number, then recursion may be acceptable, but should be documented for the use of maintainers.

It should be noted that some languages or implementations provide special (more economical) treatment of a form of recursion known as tail-recursion. In this case, the impact on computing economy is reduced. When using such a language, tail recursion may be preferred to an iterative calculation.

6.35.6 Implications for standardization


[None]

6.36 Ignored Error Status and Unhandled Exceptions [OYB]

6.36.1 Description of application vulnerability


Unpredicted faults and exceptional situations arise during the execution of code, preventing the intended functioning of the code. They are detected and reported by the language implementation or by explicit code written by the user. Different strategies and language constructs are used to report such errors and to take remedial action. Serious vulnerabilities arise when detected errors are reported but ignored or not properly handled.

6.36.2 Cross reference


CWE:

754. Improper Check for Unusual or Exceptional Conditions

JSF AV Rules: 115 and 208
MISRA C 2012: 4.7

MISRA C++ 2008: 15-3-2 and 19-3-1

CERT C guidelines: DCL09-C, ERR00-C, and ERR02-C

6.36.3 Mechanism of failure


The fundamental mechanism of failure is that the program does not react to a detected error or reacts inappropriately to it. Execution may continue outside the envelope provided by its specification, making additional errors or serious malfunction of the software likely. Alternatively, execution may terminate. The mechanism can be easily exploited to perform denial-of-service attacks.

The specific mechanism of failure depends on the error reporting and handling scheme provided by a language or applied idiomatically by its users.

In languages that expect routines to report errors via status variables, return codes, or thread-local error indicators, the error indications need to be checked after each call. As these frequent checks cost execution time and clutter the code immensely to deal with situations that may occur rarely, programmers are reluctant to apply the scheme systematically and consistently. Failure to check for and handle an arising error condition continues execution as if the error never occurred. In most cases, this continued execution in an ill-defined program state will sooner or later fail, possibly catastrophically.

The raising and handling of exceptions was introduced into languages to address these problems. They bundle the exceptional code in exception handlers, they need not cost execution time if no error is present, and they will not allow the program to continue execution by default when an error occurs, since upon raising the exception, control of execution is automatically transferred to a handler for the exception found on the call stack. The risk and the failure mechanism is that there is no such handler (unless the language enforces restrictions that guarantees its existence), resulting in the termination of the current thread of control. Also, a handler that is found might not be geared to handle the multitude of error situations that are vectored to it. Exception handling is therefore in practice more complex for the programmer than, for example, the use of status parameters. Furthermore, different languages provide exception-handling mechanisms that differ in details of their design, which in turn may lead to misunderstandings by the programmer.

The cause for the failure might be simply laziness or ignorance on the part of the programmer, or, more commonly, a mismatch in the expectations of where fault detection and fault recovery is to be done. Particularly when components meet that employ different fault detection and reporting strategies, the opportunity for mishandling recognized errors increases and creates vulnerabilities.

Another cause of the failure is the scant attention that many library providers pay to describe all error situations that calls on their routines might encounter and report. In this case, the caller cannot possibly react sensibly to all error situations that might arise. As yet another cause, the error information provided when the error occurs may be insufficiently complete to allow recovery from the error.



Different error handling mechanisms have different strengths and weaknesses. Dealing with exception handling in some languages can stress the capabilities of static analysis tools and can, in some cases, reduce the effectiveness of their analysis. Inversely, the use of error status variables can lead to confusingly complicated control structures, particularly when recovery is not possible locally. Therefore, for situations where the highest of reliability is required, the decision for or against exception handling deserves careful thought. In any case, exception-handling mechanisms should be reserved for truly unexpected situations and other situations where no local recovery is possible. Situations which are merely unusual, like the end of file condition, should be treated by explicit testing—either prior to the call which might raise the error or immediately afterward. In general, error detection, reporting, correction, and recovery should not be a late opportunistic add-on, but should be an integral part of a system design.

6.36.4 Applicable language characteristics


Whether supported by the language or not, error reporting and handling is idiomatically present in all languages. Of course, vulnerabilities caused by exceptions require a language that supports exceptions.

6.36.5 Avoiding the vulnerability or mitigating its effects


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

  • Reserve exception-handling mechanisms for truly unexpected situations and other situations where no local recovery is possible.

  • Handle exceptions by the exception handlers of an enclosing construct as close as possible to the origin of the exception but as far out as necessary to be able to deal with the error.

  • Equally, check error return values or auxiliary status variables following a call to a subprogram unless it can be demonstrated that the error condition is impossible.

  • For each routine, document all error conditions, matching error detection and reporting needs, and provide sufficient information for handling the error situation.

  • Use static analysis tools to detect and report missing or ineffective error detection or handling.

  • When execution within a particular context is abandoned due to an exception or error condition, finalize the context by closing open files, releasing resources and restoring any invariants associated with the context.

  • Retreat to a context where the fault can be handled completely (after finalizing and terminating the current context) when it is not appropriate to repair an error situation and retry the operation.

  • Always enable error checking provided by the language, the software system, or the hardware in the absence of a conclusive analysis that the error condition is rendered impossible.

  • Carefully review all error handling mechanisms, because of the complexity of error handling.

  • In applications with the highest requirements for reliability, use defense-in-depth approaches, for example, checking and handling errors even if thought to be impossible.

6.36.6 Implications for standardization


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

  • A standardized set of mechanisms for detecting and treating error conditions should be developed so that all languages to the extent possible could use them. This does not mean that all languages should use the same mechanisms as there should be a variety, but each of the mechanisms should be standardized.

Yüklə 0,54 Mb.

Dostları ilə paylaş:
1   ...   18   19   20   21   22   23   24   25   ...   54




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

    Ana səhifə