RFR: 8336095: Use-after-free in Superword leads to memory corruption

Tobias Hartmann thartmann at openjdk.org
Tue Jul 23 10:51:46 UTC 2024


[JDK-8333684](https://bugs.openjdk.org/browse/JDK-8333684) refactored code in Superword and moved a [ResourceMark](https://github.com/openjdk/jdk/blob/46c37686454321011541499a79c776f774ff2b57/src/hotspot/share/opto/superword.cpp#L1999) such that a re-allocation of the `Node_List` `IdealLoopTree::_body` now happens within a nested ResourceMark. `IdealLoopTree::_body` is still live and used once we leave the scope of that ResourceMark, leading to a use-after-free bug causing memory corruption (for details, see JBS):


V [libjvm.so+0x13068b6] Node_Array::grow(unsigned int)+0x5e (node.cpp:2776)
V [libjvm.so+0x51e4ec] Node_Array::map(unsigned int, Node*)+0x24 (node.hpp:1621)
V [libjvm.so+0x51e53b] Node_List::push(Node*)+0x33 (node.hpp:1653)
V [libjvm.so+0x149a51f] PhaseIdealLoop::register_new_node(Node*, Node*)+0xf3 (split_if.cpp:440)
V [libjvm.so+0x1197813] PhaseIdealLoop::register_new_node_with_ctrl_of(Node*, Node*)+0x3d (loopnode.hpp:1682)
V [libjvm.so+0x170b1d7] VTransformNode::register_new_node_from_vectorization(VLoopAnalyzer const&, Node*, Node*) const+0x47 (vtransform.cpp:357)
V [libjvm.so+0x170b124] VTransformVectorNode::register_new_node_from_vectorization_and_replace_scalar_nodes(VLoopAnalyzer const&, Node*) const+0x64 (vtransform.cpp:347)
V [libjvm.so+0x170af20] VTransformLoadVectorNode::apply(VLoopAnalyzer const&, GrowableArray<Node*> const&) const+0x244 (vtransform.cpp:322)
V [libjvm.so+0x1564232] VTransformGraph::apply_vectorization_for_each_vtnode(unsigned int&, unsigned int&) const+0xd2 (superword.cpp:2008)
V [libjvm.so+0x15643b0] VTransform::apply_vectorization() const+0x76 (superword.cpp:2029)
V [libjvm.so+0x15637bf] VTransform::apply()+0x201 (superword.cpp:1902)
V [libjvm.so+0x156359a] SuperWord::schedule_and_apply() const+0x15c (superword.cpp:1876)
V [libjvm.so+0x155d90e] SuperWord::SLP_extract()+0x192 (superword.cpp:477)
V [libjvm.so+0x155d705] SuperWord::transform_loop()+0x157 (superword.cpp:392)
V [libjvm.so+0x11ccbed] PhaseIdealLoop::auto_vectorize(IdealLoopTree*, VSharedData&)+0x12d (loopopts.cpp:4448)
V [libjvm.so+0x11af8fb] PhaseIdealLoop::build_and_optimize()+0x1869 (loopnode.cpp:4894)
V [libjvm.so+0x9d4331] PhaseIdealLoop::PhaseIdealLoop(PhaseIterGVN&, LoopOptsMode)+0x163 (loopnode.hpp:1117)
V [libjvm.so+0x9d4599] PhaseIdealLoop::optimize(PhaseIterGVN&, LoopOptsMode)+0x47 (loopnode.hpp:1197)
V [libjvm.so+0x9c46b8] Compile::optimize_loops(PhaseIterGVN&, LoopOptsMode)+0x68 (compile.cpp:2171)
V [libjvm.so+0x9c57c8] Compile::Optimize()+0xf56 (compile.cpp:2418)
V [libjvm.so+0x9be072] Compile::Compile(ciEnv*, ciMethod*, int, Options, DirectiveSet*)+0x15ba (compile.cpp:852)


This was reported by SAP (@MBaesken) and only happened in their internal testing. I was able to reproduce this though by adding additional verification code that I will integrate separately with [JDK-8336999](https://bugs.openjdk.org/browse/JDK-8336999) because other data structures / containers in C2 should have it as well.

The solution is to allocate `IdealLoopTree::_body` in the `comp_arena` (similar to [JDK-8325672](https://bugs.openjdk.org/browse/JDK-8325672)). My verification code now passes.

Best regards,
Tobias

-------------

Commit messages:
 - 8336095: Use-after-free in Superword leads to memory corruption

Changes: https://git.openjdk.org/jdk/pull/20297/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=20297&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8336095
  Stats: 1 line in 1 file changed: 1 ins; 0 del; 0 mod
  Patch: https://git.openjdk.org/jdk/pull/20297.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/20297/head:pull/20297

PR: https://git.openjdk.org/jdk/pull/20297


More information about the hotspot-compiler-dev mailing list