From 8aa4aaae164ac456d229cd454f3988ae5c5f0937 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 19 Dec 2021 18:12:41 +0100 Subject: [PATCH 1/2] Makefile: respect CFLAGS and LDFLAGS --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 493539b..af4c909 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ clean : rm -f capnpc-java capnpc-java.exe capnpc-java : $(CAPNPC_JAVA_SOURCES) - $(CXX) $(CAPNPC_JAVA_SOURCES) $(CXX_FLAGS) -o capnpc-java + $(CXX) $(CAPNPC_JAVA_SOURCES) $(CXX_FLAGS) $(CFLAGS) $(LDFLAGS) -o capnpc-java install: mkdir -p ${PREFIX}/bin From 89db62ae9a1f976cdb8f3309b35360ff6de01ca2 Mon Sep 17 00:00:00 2001 From: Martin Dindoffer Date: Thu, 7 Apr 2022 15:21:52 +0200 Subject: [PATCH 2/2] #122 Add bound checks for struct size Also fix incorrect bounds comparison in SegmentReader --- .../java/org/capnproto/SegmentReader.java | 2 +- .../main/java/org/capnproto/WireHelpers.java | 13 +++++++---- .../test/java/org/capnproto/LayoutTest.java | 23 +++++++++++++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/runtime/src/main/java/org/capnproto/SegmentReader.java b/runtime/src/main/java/org/capnproto/SegmentReader.java index b407d21..62a30ef 100644 --- a/runtime/src/main/java/org/capnproto/SegmentReader.java +++ b/runtime/src/main/java/org/capnproto/SegmentReader.java @@ -44,6 +44,6 @@ public class SegmentReader { public final boolean in_bounds(int start, int size) { if (start < 0 || size < 0) return false; long sizeInWords = size * Constants.BYTES_PER_WORD; - return (long) start + sizeInWords < (long) this.buffer.capacity(); + return (long) start + sizeInWords <= (long) this.buffer.capacity(); } } diff --git a/runtime/src/main/java/org/capnproto/WireHelpers.java b/runtime/src/main/java/org/capnproto/WireHelpers.java index f741d52..fe9e9b1 100644 --- a/runtime/src/main/java/org/capnproto/WireHelpers.java +++ b/runtime/src/main/java/org/capnproto/WireHelpers.java @@ -918,19 +918,24 @@ final class WireHelpers { int refTarget = WirePointer.target(refOffset, ref); FollowFarsResult resolved = followFars(ref, refTarget, segment); - int dataSizeWords = StructPointer.dataSize(resolved.ref); - if (WirePointer.kind(resolved.ref) != WirePointer.STRUCT) { throw new DecodeException("Message contains non-struct pointer where struct pointer was expected."); } - resolved.segment.arena.checkReadLimit(StructPointer.wordSize(resolved.ref)); + int dataSizeWords = StructPointer.dataSize(resolved.ref); + int ptrCount = StructPointer.ptrCount(resolved.ref); + int wordSize = dataSizeWords + ptrCount; + + resolved.segment.arena.checkReadLimit(wordSize); + if (!bounds_check(resolved.segment, resolved.ptr, wordSize)) { + throw new DecodeException("Message contains out-of-bounds struct pointer"); + } return factory.constructReader(resolved.segment, resolved.ptr * Constants.BYTES_PER_WORD, (resolved.ptr + dataSizeWords), dataSizeWords * Constants.BITS_PER_WORD, - (short)StructPointer.ptrCount(resolved.ref), + (short) ptrCount, nestingLimit - 1); } diff --git a/runtime/src/test/java/org/capnproto/LayoutTest.java b/runtime/src/test/java/org/capnproto/LayoutTest.java index 4ed6042..cce0288 100644 --- a/runtime/src/test/java/org/capnproto/LayoutTest.java +++ b/runtime/src/test/java/org/capnproto/LayoutTest.java @@ -63,6 +63,29 @@ public class LayoutTest { Assert.assertEquals(reader._getBooleanField(64), false); } + /** + * @see #122 + */ + @Test(expected = DecodeException.class) + public void readStructPointerShouldThrowDecodeExceptionOnOutOfBoundsStructPointer() { + byte[] brokenMSG = new byte[]{ + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, //declare word size of 7, with payload of only 6 words + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + ByteBuffer buffer = ByteBuffer.wrap(brokenMSG); + buffer.order(ByteOrder.LITTLE_ENDIAN); + + ReaderArena arena = new ReaderArena(new ByteBuffer[]{ buffer }, 0x7fffffffffffffffL); + + StructReader reader = WireHelpers.readStructPointer(new BareStructReader(), arena.tryGetSegment(0), 0, null, 0, 0x7fffffff); + } + private class BareStructBuilder implements StructBuilder.Factory { private StructSize structSize;