Skip to content

Commit

Permalink
Fix use after free during creation of Promise reactions.
Browse files Browse the repository at this point in the history
The ecma_enqueue_promise_reaction_job() function allocates memory,
which might trigger a GC run. During this GC the objects in the
reactions collection are not marked.

Fixes jerryscript-project#2486.
Fixes jerryscript-project#2506.
Fixes jerryscript-project#2541.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg [email protected]
  • Loading branch information
zherczeg committed Oct 4, 2018
1 parent 7717d2e commit f204815
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
16 changes: 10 additions & 6 deletions jerry-core/ecma/operations/ecma-promise-object.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,6 @@ ecma_promise_trigger_reactions (ecma_collection_header_t *reactions, /**< lists
ecma_enqueue_promise_reaction_job (*ecma_value_p, value);
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
}

ecma_free_values_collection (reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
} /* ecma_promise_trigger_reactions */

/**
Expand All @@ -180,12 +178,15 @@ ecma_reject_promise (ecma_value_t promise, /**< promise */
first and creating a new one might cause a heap after use event. */
ecma_collection_header_t *reject_reactions = promise_p->reject_reactions;
ecma_collection_header_t *fulfill_reactions = promise_p->fulfill_reactions;

/* Fulfill reactions will never be triggered. */
ecma_promise_trigger_reactions (reject_reactions, reason);

promise_p->reject_reactions = ecma_new_values_collection ();
promise_p->fulfill_reactions = ecma_new_values_collection ();

/* Fulfill reactions will never be triggered. */
ecma_free_values_collection (reject_reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
ecma_free_values_collection (fulfill_reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
ecma_promise_trigger_reactions (reject_reactions, reason);
} /* ecma_reject_promise */

/**
Expand All @@ -209,12 +210,15 @@ ecma_fulfill_promise (ecma_value_t promise, /**< promise */
first and creating a new one might cause a heap after use event. */
ecma_collection_header_t *reject_reactions = promise_p->reject_reactions;
ecma_collection_header_t *fulfill_reactions = promise_p->fulfill_reactions;

/* Reject reactions will never be triggered. */
ecma_promise_trigger_reactions (fulfill_reactions, value);

promise_p->reject_reactions = ecma_new_values_collection ();
promise_p->fulfill_reactions = ecma_new_values_collection ();

/* Reject reactions will never be triggered. */
ecma_free_values_collection (reject_reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
ecma_promise_trigger_reactions (fulfill_reactions, value);
ecma_free_values_collection (fulfill_reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
} /* ecma_fulfill_promise */

/**
Expand Down
18 changes: 18 additions & 0 deletions tests/jerry/es2015/regression-test-issue-2486.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright JS Foundation and other contributors, http://js.foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

Object.setPrototypeOf(Math, Int32Array);
for (var i = 0; i < 200; i++) {
Promise.race([, [,] % {}]).then();
}

0 comments on commit f204815

Please sign in to comment.