2089
The table(s) below shows the weaknesses and high level categories that are related to this
weakness. These relationships are defined as ChildOf, ParentOf, MemberOr and give insight to
similar items that may exist at higher and lower levels of abstraction. In addition, relationships such
as PeerOf and CanAlsoBe are defined to show similar weaknesses that may want to be explored.
Relevant to the view "Research Concepts" (CWE-1000)
Nature Type ID Name Page
ChildOf 691 Insufficient Control Flow Management 1517
PeerOf 663 Use of a Non-reentrant Function in a Concurrent Context 1452
CanPrecede 416 Use After Free 1012
Relevant to the view "Software Development" (CWE-699)
Nature Type ID Name Page
MemberOf 371 State Issues 2321
Weakness Ordinalities
Primary :
Applicable Platforms
Language : Not Language-Specific (Prevalence = Undetermined)
Common Consequences
Scope Impact Likelihood
Integrity Unexpected State
Exploitation of this weakness can leave the application in
an unexpected state and cause variables to be reassigned
before the first invocation has completed. This may
eventually result in memory corruption or unexpected code
execution.
Unknown
Potential Mitigations
Phase: Architecture and Design
When architecting a system that will execute untrusted code in response to events, consider
executing the untrusted event handlers asynchronously (asynchronous message passing) as
opposed to executing them synchronously at the time each event fires. The untrusted code
should execute at the start of the next iteration of the thread's message loop. In this way, calls
into non-reentrant code are strictly serialized, so that each operation completes fully before the
next operation begins. Special attention must be paid to all places where type coercion may
result in script execution. Performing all needed coercions at the very beginning of an operation
can help reduce the chance of operations executing at unexpected junctures.
Effectiveness = High
Phase: Implementation
Make sure the code (e.g., function or class) in question is reentrant by not leveraging non-local
data, not modifying its own code, and not calling other non-reentrant code.
Effectiveness = High
Demonstrative Examples
Example 1:
The implementation of the Widget class in the following C++ code is an example of code that is not
designed to be reentrant. If an invocation of a method of Widget inadvertently produces a second
nested invocation of a method of Widget, then data member backgroundImage may unexpectedly
change during execution of the outer call.
CWE Version 4.14
CWE-1265: Unintended Reentrant Invocation of Non-reentrant Code Via Nested Calls
CWE-1265: Unintended Reentrant Invocation
of Non-reentrant Code Via Nested Calls 2090
Example Language: C++ (Bad)
class Widget
{
private:
Image* backgroundImage;
public:
void click()
{
if (backgroundImage)
{
backgroundImage->click();
}
}
void changeBackgroundImage(Image* newImage)
{
if (backgroundImage)
{
delete backgroundImage;
}
backgroundImage = newImage;
}
}
class Image
{
public:
void click()
{
scriptEngine->fireOnImageClick();
/* perform some operations using "this" pointer */
}
}
Looking closer at this example, Widget::click() calls backgroundImage->click(), which in
turn calls scriptEngine->fireOnImageClick(). The code within fireOnImageClick() invokes
the appropriate script handler routine as defined by the document being rendered. In this
scenario this script routine is supplied by an adversary and this malicious script makes a call to
Widget::changeBackgroundImage(), deleting the Image object pointed to by backgroundImage.
When control returns to Image::click, the function's backgroundImage "this" pointer (which is the
former value of backgroundImage) is a dangling pointer. The root of this weakness is that while
one operation on Widget (click) is in the midst of executing, a second operation on the Widget
object may be invoked (in this case, the second invocation is a call to different method, namely
changeBackgroundImage) that modifies the non-local variable.
Example 2:
This is another example of C++ code that is not designed to be reentrant.
Example Language: C++ (Bad)
class Request
{
private:
std::string uri;
/* ... */
public:
void setup(ScriptObject* _uri)
{
this->uri = scriptEngine->coerceToString(_uri);
/* ... */
}
void send(ScriptObject* _data)
{
Credentials credentials = GetCredentials(uri);
std::string data = scriptEngine->coerceToString(_data);
doSend(uri, credentials, data);
CWE Version 4.14
CWE-1266: Improper Scrubbing of Sensitive Data from Decommissioned Device
CWE-1266: Improper Scrubbing of Sensitive Data from Decommissioned Device