Skip to content
This repository was archived by the owner on Sep 19, 2023. It is now read-only.
/ jdk20u Public archive

Commit ac96054

Browse files
committed
8302595: use-after-free related to GraphKit::clone_map
Backport-of: 3cc459b6c2f571987dc36fd548a2b830f0b33a0a
1 parent fcd422d commit ac96054

File tree

7 files changed

+47
-7
lines changed

7 files changed

+47
-7
lines changed

src/hotspot/share/opto/compile.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,8 @@ class Compile : public Phase {
939939
// Parsing, optimization
940940
PhaseGVN* initial_gvn() { return _initial_gvn; }
941941
Unique_Node_List* for_igvn() { return _for_igvn; }
942-
inline void record_for_igvn(Node* n); // Body is after class Unique_Node_List.
942+
inline void record_for_igvn(Node* n); // Body is after class Unique_Node_List in node.hpp.
943+
inline void remove_for_igvn(Node* n); // Body is after class Unique_Node_List in node.hpp.
943944
void set_initial_gvn(PhaseGVN *gvn) { _initial_gvn = gvn; }
944945
void set_for_igvn(Unique_Node_List *for_igvn) { _for_igvn = for_igvn; }
945946

src/hotspot/share/opto/graphKit.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,29 @@ SafePointNode* GraphKit::clone_map() {
735735
return clonemap;
736736
}
737737

738+
//-----------------------------destruct_map_clone------------------------------
739+
//
740+
// Order of destruct is important to increase the likelyhood that memory can be re-used. We need
741+
// to destruct/free/delete in the exact opposite order as clone_map().
742+
void GraphKit::destruct_map_clone(SafePointNode* sfp) {
743+
if (sfp == nullptr) return;
744+
745+
Node* mem = sfp->memory();
746+
JVMState* jvms = sfp->jvms();
747+
748+
if (jvms != nullptr) {
749+
delete jvms;
750+
}
751+
752+
remove_for_igvn(sfp);
753+
gvn().clear_type(sfp);
754+
sfp->destruct(&_gvn);
755+
756+
if (mem != nullptr) {
757+
gvn().clear_type(mem);
758+
mem->destruct(&_gvn);
759+
}
760+
}
738761

739762
//-----------------------------set_map_clone-----------------------------------
740763
void GraphKit::set_map_clone(SafePointNode* m) {

src/hotspot/share/opto/graphKit.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class GraphKit : public Phase {
9494
void* barrier_set_state() const { return C->barrier_set_state(); }
9595

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

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

174+
// Reverses the work done by clone_map(). Should only be used when the node returned by
175+
// clone_map() is ultimately not used. Calling Node::destruct directly in the previously
176+
// mentioned circumstance instead of this method may result in use-after-free.
177+
void destruct_map_clone(SafePointNode* sfp);
178+
173179
// Set the map to a clone of the given one.
174180
void set_map_clone(SafePointNode* m);
175181

src/hotspot/share/opto/library_call.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -1637,7 +1637,7 @@ bool LibraryCallKit::inline_string_char_access(bool is_store) {
16371637
set_sp(old_sp);
16381638
return false;
16391639
}
1640-
old_map->destruct(&_gvn);
1640+
destruct_map_clone(old_map);
16411641
if (is_store) {
16421642
access_store_at(value, adr, TypeAryPtr::BYTES, ch, TypeInt::CHAR, T_CHAR, IN_HEAP | MO_UNORDERED | C2_MISMATCHED);
16431643
} else {
@@ -2352,7 +2352,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c
23522352
mismatched = true; // conservatively mark all "wide" on-heap accesses as mismatched
23532353
}
23542354

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

23582358
if (mismatched) {
@@ -2603,7 +2603,7 @@ bool LibraryCallKit::inline_unsafe_load_store(const BasicType type, const LoadSt
26032603
return false;
26042604
}
26052605

2606-
old_map->destruct(&_gvn);
2606+
destruct_map_clone(old_map);
26072607

26082608
// For CAS, unlike inline_unsafe_access, there seems no point in
26092609
// trying to refine types. Just use the coarse types here.

src/hotspot/share/opto/node.hpp

+5
Original file line numberDiff line numberDiff line change
@@ -1667,6 +1667,11 @@ inline void Compile::record_for_igvn(Node* n) {
16671667
_for_igvn->push(n);
16681668
}
16691669

1670+
// Inline definition of Compile::remove_for_igvn must be deferred to this point.
1671+
inline void Compile::remove_for_igvn(Node* n) {
1672+
_for_igvn->remove(n);
1673+
}
1674+
16701675
//------------------------------Node_Stack-------------------------------------
16711676
class Node_Stack {
16721677
friend class VMStructs;

src/hotspot/share/opto/phaseX.hpp

+5
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,11 @@ class PhaseTransform : public Phase {
239239
assert(t != NULL, "type must not be null");
240240
_types.map(n->_idx, t);
241241
}
242+
void clear_type(const Node* n) {
243+
if (n->_idx < _types.Size()) {
244+
_types.map(n->_idx, NULL);
245+
}
246+
}
242247
// Record an initial type for a node, the node's bottom type.
243248
void set_type_bottom(const Node* n) {
244249
// Use this for initialization when bottom_type() (or better) is not handy.

src/hotspot/share/opto/vectorIntrinsics.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -1114,7 +1114,7 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
11141114
set_result(box);
11151115
}
11161116

1117-
old_map->destruct(&_gvn);
1117+
destruct_map_clone(old_map);
11181118

11191119
if (needs_cpu_membar) {
11201120
insert_mem_bar(Op_MemBarCPUOrder);
@@ -1373,7 +1373,7 @@ bool LibraryCallKit::inline_vector_mem_masked_operation(bool is_store) {
13731373
set_result(box);
13741374
}
13751375

1376-
old_map->destruct(&_gvn);
1376+
destruct_map_clone(old_map);
13771377

13781378
if (can_access_non_heap) {
13791379
insert_mem_bar(Op_MemBarCPUOrder);
@@ -1586,7 +1586,7 @@ bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) {
15861586
set_result(box);
15871587
}
15881588

1589-
old_map->destruct(&_gvn);
1589+
destruct_map_clone(old_map);
15901590

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

0 commit comments

Comments
 (0)