[jdk19] RFR: 8289148: j.l.foreign.VaList::nextVarg call could throw IndexOutOfBoundsException or even crash the VM
Maurizio Cimadamore
mcimadamore at openjdk.org
Tue Jul 5 11:30:53 UTC 2022
On Wed, 29 Jun 2022 13:40:01 GMT, Jorn Vernee <jvernee at openjdk.org> wrote:
> This patch changes all VaList implementations to throw `NoSuchElementException` when out of bounds reads occur on a VaList that is created using the Java builder API. The docs are updated accordingly.
>
> For VaLists that are created from native addresses, we don't know their bounds, so we can not throw exceptions in that case.
>
> Testing: `jdk_foreign` test suite on all platforms that implement VaList.
Looks good - I've added some comments, esp. in the javadoc
src/java.base/share/classes/java/lang/foreign/VaList.java line 61:
> 59: * Particularly, variable argument lists created using {@link #make(Consumer, MemorySession)} are able to detect out-of-bounds reads,
> 60: * while variable argument lists crearted using {@link #ofAddress(MemoryAddress, MemorySession)} are not.
> 61: * <p>
Suggestion:
* <h2>Safety considerations</h2>
* A variable argument list can be thought of as a cursor into a memory segment which stores one or
* more elements, with given layouts. The {@linkplain #nextVarg(ValueLayout.OfInt) methods} used to retrieve elements from
* a variable argument list update the cursor position; as such it is possible for clients to access elements
* outside the spatial bounds of the variable argument list.
* <p>
* A variable argument list attempts to detect out-of-bounds access on a best-effort basis.
* Whether this detection succeeds depends on the factory method used to create the variable argument list:
* <ul>
* <li>Variable argument lists created <em>safely</em>, using {@link #make(Consumer, MemorySession)} are built on top of
* native memory segments that are sized correctly. As such, they are capable of detecting out-of-bounds reads;</li>
* <li>Variable argument lists created <em>unsafely</em>, using {@link #ofAddress(MemoryAddress, MemorySession)} are built on top
* of segments whose size is unknown. As such they cannot detect out-of-bounds reads</li>
* <p>```
src/java.base/share/classes/java/lang/foreign/VaList.java line 99:
> 97: * @throws WrongThreadException if this method is called from a thread other than the thread owning
> 98: * the {@linkplain #session() session} associated with this variable argument list.
> 99: * @throws NoSuchElementException if an out-of-bounds read is detected.
I'd insert a link to the safety section, where the link text is "out-of-bounds".
src/java.base/share/classes/java/lang/foreign/VaList.java line 202:
> 200: * restricted methods, and use safe and supported functionalities, where possible.
> 201: *
> 202: * @implNote variable argument lists created using this method can not detect out-of-bound reads.
Links here too
src/java.base/share/classes/jdk/internal/foreign/abi/x64/sysv/SysVVaList.java line 291:
> 289: }
> 290:
> 291: private void checkRegAreaElement(MemoryLayout layout, TypeClass typeClass) {
should this be `checkRegSaveAreaElement` ?
test/jdk/java/foreign/valist/VaListTest.java line 827:
> 825:
> 826: @DataProvider
> 827: public static Object[][] overflow() {
nice test!
-------------
PR: https://git.openjdk.org/jdk19/pull/91
More information about the core-libs-dev
mailing list