Skip to content
This repository has been archived by the owner on Sep 19, 2023. It is now read-only.

Commit

Permalink
8302595: use-after-free related to GraphKit::clone_map
Browse files Browse the repository at this point in the history
Backport-of: 3cc459b6c2f571987dc36fd548a2b830f0b33a0a
  • Loading branch information
TobiHartmann committed Apr 4, 2023
1 parent fcd422d commit ac96054
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 7 deletions.
3 changes: 2 additions & 1 deletion src/hotspot/share/opto/compile.hpp
Expand Up @@ -939,7 +939,8 @@ class Compile : public Phase {
// Parsing, optimization
PhaseGVN* initial_gvn() { return _initial_gvn; }
Unique_Node_List* for_igvn() { return _for_igvn; }
inline void record_for_igvn(Node* n); // Body is after class Unique_Node_List.
inline void record_for_igvn(Node* n); // Body is after class Unique_Node_List in node.hpp.
inline void remove_for_igvn(Node* n); // Body is after class Unique_Node_List in node.hpp.
void set_initial_gvn(PhaseGVN *gvn) { _initial_gvn = gvn; }
void set_for_igvn(Unique_Node_List *for_igvn) { _for_igvn = for_igvn; }

Expand Down
23 changes: 23 additions & 0 deletions src/hotspot/share/opto/graphKit.cpp
Expand Up @@ -735,6 +735,29 @@ SafePointNode* GraphKit::clone_map() {
return clonemap;
}

//-----------------------------destruct_map_clone------------------------------
//
// Order of destruct is important to increase the likelyhood that memory can be re-used. We need
// to destruct/free/delete in the exact opposite order as clone_map().
void GraphKit::destruct_map_clone(SafePointNode* sfp) {
if (sfp == nullptr) return;

Node* mem = sfp->memory();
JVMState* jvms = sfp->jvms();

if (jvms != nullptr) {
delete jvms;
}

remove_for_igvn(sfp);
gvn().clear_type(sfp);
sfp->destruct(&_gvn);

if (mem != nullptr) {
gvn().clear_type(mem);
mem->destruct(&_gvn);
}
}

//-----------------------------set_map_clone-----------------------------------
void GraphKit::set_map_clone(SafePointNode* m) {
Expand Down
6 changes: 6 additions & 0 deletions src/hotspot/share/opto/graphKit.hpp
Expand Up @@ -94,6 +94,7 @@ class GraphKit : public Phase {
void* barrier_set_state() const { return C->barrier_set_state(); }

void record_for_igvn(Node* n) const { C->record_for_igvn(n); } // delegate to Compile
void remove_for_igvn(Node* n) const { C->remove_for_igvn(n); }

// Handy well-known nodes:
Node* null() const { return zerocon(T_OBJECT); }
Expand Down Expand Up @@ -170,6 +171,11 @@ class GraphKit : public Phase {
// Clone the existing map state. (Implements PreserveJVMState.)
SafePointNode* clone_map();

// Reverses the work done by clone_map(). Should only be used when the node returned by
// clone_map() is ultimately not used. Calling Node::destruct directly in the previously
// mentioned circumstance instead of this method may result in use-after-free.
void destruct_map_clone(SafePointNode* sfp);

// Set the map to a clone of the given one.
void set_map_clone(SafePointNode* m);

Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/share/opto/library_call.cpp
Expand Up @@ -1637,7 +1637,7 @@ bool LibraryCallKit::inline_string_char_access(bool is_store) {
set_sp(old_sp);
return false;
}
old_map->destruct(&_gvn);
destruct_map_clone(old_map);
if (is_store) {
access_store_at(value, adr, TypeAryPtr::BYTES, ch, TypeInt::CHAR, T_CHAR, IN_HEAP | MO_UNORDERED | C2_MISMATCHED);
} else {
Expand Down Expand Up @@ -2352,7 +2352,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c
mismatched = true; // conservatively mark all "wide" on-heap accesses as mismatched
}

old_map->destruct(&_gvn);
destruct_map_clone(old_map);
assert(!mismatched || alias_type->adr_type()->is_oopptr(), "off-heap access can't be mismatched");

if (mismatched) {
Expand Down Expand Up @@ -2603,7 +2603,7 @@ bool LibraryCallKit::inline_unsafe_load_store(const BasicType type, const LoadSt
return false;
}

old_map->destruct(&_gvn);
destruct_map_clone(old_map);

// For CAS, unlike inline_unsafe_access, there seems no point in
// trying to refine types. Just use the coarse types here.
Expand Down
5 changes: 5 additions & 0 deletions src/hotspot/share/opto/node.hpp
Expand Up @@ -1667,6 +1667,11 @@ inline void Compile::record_for_igvn(Node* n) {
_for_igvn->push(n);
}

// Inline definition of Compile::remove_for_igvn must be deferred to this point.
inline void Compile::remove_for_igvn(Node* n) {
_for_igvn->remove(n);
}

//------------------------------Node_Stack-------------------------------------
class Node_Stack {
friend class VMStructs;
Expand Down
5 changes: 5 additions & 0 deletions src/hotspot/share/opto/phaseX.hpp
Expand Up @@ -239,6 +239,11 @@ class PhaseTransform : public Phase {
assert(t != NULL, "type must not be null");
_types.map(n->_idx, t);
}
void clear_type(const Node* n) {
if (n->_idx < _types.Size()) {
_types.map(n->_idx, NULL);
}
}
// Record an initial type for a node, the node's bottom type.
void set_type_bottom(const Node* n) {
// Use this for initialization when bottom_type() (or better) is not handy.
Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/share/opto/vectorIntrinsics.cpp
Expand Up @@ -1114,7 +1114,7 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
set_result(box);
}

old_map->destruct(&_gvn);
destruct_map_clone(old_map);

if (needs_cpu_membar) {
insert_mem_bar(Op_MemBarCPUOrder);
Expand Down Expand Up @@ -1373,7 +1373,7 @@ bool LibraryCallKit::inline_vector_mem_masked_operation(bool is_store) {
set_result(box);
}

old_map->destruct(&_gvn);
destruct_map_clone(old_map);

if (can_access_non_heap) {
insert_mem_bar(Op_MemBarCPUOrder);
Expand Down Expand Up @@ -1586,7 +1586,7 @@ bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) {
set_result(box);
}

old_map->destruct(&_gvn);
destruct_map_clone(old_map);

C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
return true;
Expand Down

1 comment on commit ac96054

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.