Skip to content

Commit

Permalink
8311583: tableswitch broken by JDK-8310577
Browse files Browse the repository at this point in the history
Reviewed-by: dholmes, dlong
  • Loading branch information
coleenp committed Jul 13, 2023
1 parent 6895deb commit 135f64e
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 7 deletions.
16 changes: 9 additions & 7 deletions src/hotspot/share/interpreter/bytecodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,12 +385,13 @@ int Bytecodes::special_length_at(Bytecodes::Code code, address bcp, address end)
if (end != nullptr && aligned_bcp + 3*jintSize >= end) {
return -1; // don't read past end of code buffer
}
int lo = Bytes::get_Java_u4(aligned_bcp + 1*jintSize);
int hi = Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
int len = (int)(aligned_bcp - bcp) + (3 + hi - lo + 1)*jintSize;
// Promote calculation to 64 bits to do range checks, used by the verifier.
int64_t lo = (int)Bytes::get_Java_u4(aligned_bcp + 1*jintSize);
int64_t hi = (int)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
int64_t len = (aligned_bcp - bcp) + (3 + hi - lo + 1)*jintSize;
// only return len if it can be represented as a positive int;
// return -1 otherwise
return (len > 0 && len == (int)len) ? len : -1;
return (len > 0 && len == (int)len) ? (int)len : -1;
}

case _lookupswitch: // fall through
Expand All @@ -400,11 +401,12 @@ int Bytecodes::special_length_at(Bytecodes::Code code, address bcp, address end)
if (end != nullptr && aligned_bcp + 2*jintSize >= end) {
return -1; // don't read past end of code buffer
}
int npairs = Bytes::get_Java_u4(aligned_bcp + jintSize);
int len = (int)(aligned_bcp - bcp) + (2 + 2*npairs)*jintSize;
// Promote calculation to 64 bits to do range checks, used by the verifier.
int64_t npairs = (int)Bytes::get_Java_u4(aligned_bcp + jintSize);
int64_t len = (aligned_bcp - bcp) + (2 + 2*npairs)*jintSize;
// only return len if it can be represented as a positive int;
// return -1 otherwise
return (len > 0 && len == (int)len) ? len : -1;
return (len > 0 && len == (int)len) ? (int)len : -1;
}
default:
// Note: Length functions must return <=0 for invalid bytecodes.
Expand Down
43 changes: 43 additions & 0 deletions test/hotspot/jtreg/runtime/verifier/LookupSwitchp1.jasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

// This test generates a npairs that overflows int so lookupswitch is an invalid bytecode

public class LookupSwitchp1 version 50:0 {

public static Method runLookup:"()V"
stack 4 locals 3
{
iconst_0;
bytecode 171; // lookupswitch
bytecode 0,0; // padding
bytecode 0,0,0,16; // default target == L17
bytecode 0x80,0,0,0; // 0x80000000 npairs
bytecode 0,0,0,0; // one match-offset pair
bytecode 0,0,0,16; // also goes to target
// incomplete npair table
L17:
iconst_0;
ireturn;
}
}
43 changes: 43 additions & 0 deletions test/hotspot/jtreg/runtime/verifier/TableSwitchp1.jasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

// This test generates (high - lo) that overflows int so tableswitch is an invalid bytecode
// If treated as unsigned lo > high but the tableswitch operands are signed int.

public class TableSwitchp1 version 50:0 {

public static Method runTable:"()V"
stack 4 locals 3
{
iconst_0;
bytecode 170; // tableswitch
bytecode 0,0; // padding
bytecode 0,0,0,15; // default target == L16
bytecode 0x80,0,0,0; // 0x80000000 low
bytecode 0x7F,0xFF,0xFF,0xFF; // 0x7fffffff high
// illegal empty table
L16:
iconst_0;
ireturn;
}
}
58 changes: 58 additions & 0 deletions test/hotspot/jtreg/runtime/verifier/TestTableSwitch.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;

/*
* @test TestTableSwitch
* @bug 8311583
* @library /test/lib
* @compile TableSwitchp1.jasm LookupSwitchp1.jasm
* @run driver TestTableSwitch
*/

public class TestTableSwitch {

public static void main(String[] args) throws Exception {
if (args.length == 1) {
if (args[0].equals("runTable")) {
TableSwitchp1.runTable();
} else { // if (args[0].equals("runLookup"))
LookupSwitchp1.runLookup();
}
} else {
ProcessBuilder pb = ProcessTools.createTestJvm("TestTableSwitch", "runTable");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("java.lang.VerifyError: Bad instruction");
output.shouldHaveExitValue(1);

pb = ProcessTools.createTestJvm("TestTableSwitch", "runLookup");
output = new OutputAnalyzer(pb.start());
output.shouldContain("java.lang.VerifyError: Bad instruction");
output.shouldHaveExitValue(1);
}
}
}


1 comment on commit 135f64e

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