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

Commit

Permalink
8302594: use-after-free in Node::destruct
Browse files Browse the repository at this point in the history
Backport-of: 2e3cea01daca594dfa4477439a9849eea19b249e
  • Loading branch information
TobiHartmann committed Apr 4, 2023
1 parent aa6d177 commit fcd422d
Showing 1 changed file with 31 additions and 27 deletions.
58 changes: 31 additions & 27 deletions src/hotspot/share/opto/node.cpp
Expand Up @@ -616,33 +616,7 @@ void Node::destruct(PhaseValues* phase) {
//assert(def->out(def->outcnt()-1) == (Node *)this,"bad def-use hacking in reclaim");
}
assert(outcnt() == 0, "deleting a node must not leave a dangling use");
// See if the input array was allocated just prior to the object
int edge_size = _max*sizeof(void*);
int out_edge_size = _outmax*sizeof(void*);
char *edge_end = ((char*)_in) + edge_size;
char *out_array = (char*)(_out == NO_OUT_ARRAY? NULL: _out);
int node_size = size_of();

// Free the output edge array
if (out_edge_size > 0) {
compile->node_arena()->Afree(out_array, out_edge_size);
}

// Free the input edge array and the node itself
if( edge_end == (char*)this ) {
// It was; free the input array and object all in one hit
#ifndef ASSERT
compile->node_arena()->Afree(_in,edge_size+node_size);
#endif
} else {
// Free just the input array
compile->node_arena()->Afree(_in,edge_size);

// Free just the object
#ifndef ASSERT
compile->node_arena()->Afree(this,node_size);
#endif
}
if (is_macro()) {
compile->remove_macro_node(this);
}
Expand All @@ -665,13 +639,43 @@ void Node::destruct(PhaseValues* phase) {
}
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
bs->unregister_potential_barrier_node(this);

// See if the input array was allocated just prior to the object
int edge_size = _max*sizeof(void*);
int out_edge_size = _outmax*sizeof(void*);
char *in_array = ((char*)_in);
char *edge_end = in_array + edge_size;
char *out_array = (char*)(_out == NO_OUT_ARRAY? NULL: _out);
int node_size = size_of();

#ifdef ASSERT
// We will not actually delete the storage, but we'll make the node unusable.
compile->remove_modified_node(this);
*(address*)this = badAddress; // smash the C++ vtbl, probably
_in = _out = (Node**) badAddress;
_max = _cnt = _outmax = _outcnt = 0;
compile->remove_modified_node(this);
#endif

// Free the output edge array
if (out_edge_size > 0) {
compile->node_arena()->Afree(out_array, out_edge_size);
}

// Free the input edge array and the node itself
if( edge_end == (char*)this ) {
// It was; free the input array and object all in one hit
#ifndef ASSERT
compile->node_arena()->Afree(in_array, edge_size+node_size);
#endif
} else {
// Free just the input array
compile->node_arena()->Afree(in_array, edge_size);

// Free just the object
#ifndef ASSERT
compile->node_arena()->Afree(this, node_size);
#endif
}
}

//------------------------------grow-------------------------------------------
Expand Down

1 comment on commit fcd422d

@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.