From 000a42a913a0d4fee3868526512e087c4203aab9 Mon Sep 17 00:00:00 2001 From: Dan Heidinga Date: Tue, 14 May 2019 13:59:15 -0400 Subject: [PATCH 1/3] Correct buffer size to fix memory corruption The analysis in eclipse/openj9#5696 shows that there is a out of bounds access that is fixed by increasing the buffer size by 8. Validated by having the VM increase all unsafe allocates by 8 and the problem no longer occurs. fixes: #79 Signed-off-by: Dan Heidinga --- runtime/src/main/java/com4j/Variant.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/src/main/java/com4j/Variant.java b/runtime/src/main/java/com4j/Variant.java index 92fae32..58d0c67 100644 --- a/runtime/src/main/java/com4j/Variant.java +++ b/runtime/src/main/java/com4j/Variant.java @@ -360,10 +360,10 @@ public int comEnumValue() { * Creates an empty {@link Variant}. */ public Variant() { - image = ByteBuffer.allocateDirect(16); + image = ByteBuffer.allocateDirect(24); image.order(ByteOrder.LITTLE_ENDIAN); // The initial content of a buffer is, in general, undefined. See the documentation of java.nio.Buffer. - byte[] b = new byte[16]; // this initializes the array with zeros + byte[] b = new byte[24]; // this initializes the array with zeros image.put(b); // this prints the zeros to the buffer to guarantee, that the buffer is initialized with zeros. image.position(0); } From f7344f4a6449e3e35195a2475a3122ec7d021fa3 Mon Sep 17 00:00:00 2001 From: Dan Heidinga Date: Wed, 15 May 2019 09:39:49 -0400 Subject: [PATCH 2/3] Determine Variant structure size correctly on 32 vs 64bit Structure contains pointers so its size depends on whether the system is 32 or 64 bit Signed-off-by: Dan Heidinga --- runtime/src/main/java/com4j/Variant.java | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/runtime/src/main/java/com4j/Variant.java b/runtime/src/main/java/com4j/Variant.java index 58d0c67..04211f1 100644 --- a/runtime/src/main/java/com4j/Variant.java +++ b/runtime/src/main/java/com4j/Variant.java @@ -356,14 +356,30 @@ public int comEnumValue() { } } + /** + * Determine the correct size of {@link Variant}. + * + * The size of the variant depends on whether this is + * a 32 or 64 bit system due to pointers in the structure + * definition. See https://docs.microsoft.com/en-gb/windows/desktop/api/oaidl/ns-oaidl-tagvariant + */ + private static int variantSize() { + String model = System.getProperty("sun.arch.data.model"); + if (model.equals("64")) { + return 24; + } + return 16; + } + /** * Creates an empty {@link Variant}. */ public Variant() { - image = ByteBuffer.allocateDirect(24); + final int variantSize = variantSize(); + image = ByteBuffer.allocateDirect(variantSize); image.order(ByteOrder.LITTLE_ENDIAN); // The initial content of a buffer is, in general, undefined. See the documentation of java.nio.Buffer. - byte[] b = new byte[24]; // this initializes the array with zeros + byte[] b = new byte[variantSize]; // this initializes the array with zeros image.put(b); // this prints the zeros to the buffer to guarantee, that the buffer is initialized with zeros. image.position(0); } From bf099f288a2ba86b7f0a18d810e2d2f8fd615d65 Mon Sep 17 00:00:00 2001 From: Dan Heidinga Date: Wed, 15 May 2019 10:18:46 -0400 Subject: [PATCH 3/3] Use `os.arch` and move variantSize check into static final variable Signed-off-by: Dan Heidinga --- runtime/src/main/java/com4j/Variant.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/runtime/src/main/java/com4j/Variant.java b/runtime/src/main/java/com4j/Variant.java index 04211f1..8203244 100644 --- a/runtime/src/main/java/com4j/Variant.java +++ b/runtime/src/main/java/com4j/Variant.java @@ -364,18 +364,20 @@ public int comEnumValue() { * definition. See https://docs.microsoft.com/en-gb/windows/desktop/api/oaidl/ns-oaidl-tagvariant */ private static int variantSize() { - String model = System.getProperty("sun.arch.data.model"); - if (model.equals("64")) { + /* Typical os.arch values: `x86_64`, `amd64` */ + String model = System.getProperty("os.arch"); + if (model.indexOf("64") != -1) { return 24; } return 16; } + private static final int variantSize = variantSize(); + /** * Creates an empty {@link Variant}. */ public Variant() { - final int variantSize = variantSize(); image = ByteBuffer.allocateDirect(variantSize); image.order(ByteOrder.LITTLE_ENDIAN); // The initial content of a buffer is, in general, undefined. See the documentation of java.nio.Buffer.