CWE-1265: Unintended Reentrant Invocation of Non-reentrant Code Via Nested Calls

Description

During execution of non-reentrant code, the product performs a call that unintentionally produces a nested invocation of the non-reentrant code.

Submission Date :

Dec. 20, 2018, midnight

Modification Date :

2023-06-29 00:00:00+00:00

Organization :

Trend Micro
Extended Description

In a complex product, a single function call may lead to many different possible code paths, some of which may involve deeply nested calls. It may be difficult to foresee all possible code paths that could emanate from a given function call. In some systems, an external actor can manipulate inputs to the system and thereby achieve a wide range of possible control flows. This is frequently a concern in products that execute scripts from untrusted sources. Examples of such products are web browsers and PDF readers. A weakness is present when one of the possible code paths resulting from a function call alters program state that the original caller assumes to be unchanged during the call.

Example Vulnerable Codes

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.


Image* backgroundImage;


backgroundImage->click();if (backgroundImage){}

delete backgroundImage;
if (backgroundImage){}backgroundImage = newImage;void click(){}void changeBackgroundImage(Image* newImage){}private:public:


scriptEngine->fireOnImageClick();/* perform some operations using "this" pointer */void click(){}public:class Widget{}class Image{}

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.



std::string uri;/* ... */


this->uri = scriptEngine->coerceToString(_uri);/* ... */

Credentials credentials = GetCredentials(uri);std::string data = scriptEngine->coerceToString(_data);doSend(uri, credentials, data);void setup(ScriptObject* _uri){}void send(ScriptObject* _data){}private:public:class Request{}

The expected order of operations is a call to Request::setup(), followed by a call to Request::send(). Request::send() calls scriptEngine->coerceToString(_data) to coerce a script-provided parameter into a string. This operation may produce script execution. For example, if the script language is ECMAScript, arbitrary script execution may result if _data is an adversary-supplied ECMAScript object having a custom toString method. If the adversary's script makes a new call to Request::setup, then when control returns to Request::send, the field uri and the local variable credentials will no longer be consistent with one another. As a result, credentials for one resource will be shared improperly with a different resource. The root of this weakness is that while one operation on Request (send) is in the midst of executing, a second operation may be invoked (setup).

Related Weaknesses

This table shows the weaknesses and high level categories that are related to this weakness. These relationships are defined to give an overview of the different insight to similar items that may exist at higher and lower levels of abstraction.

Visit http://cwe.mitre.org/ for more details.