Fix integer overflow in bounds checking
This commit is contained in:
parent
ced3f11e6f
commit
e77372b1cd
4 changed files with 54 additions and 6 deletions
|
@ -39,11 +39,13 @@ public class SegmentReader {
|
|||
return buffer.getLong(index * Constants.BYTES_PER_WORD);
|
||||
}
|
||||
|
||||
// Verify that the `size`-long (in words) range starting at word index
|
||||
// `start` is within bounds.
|
||||
public final boolean in_bounds(int start, int size) {
|
||||
/**
|
||||
* Verify that the `size`-long (in words) range starting at word index
|
||||
* `start` is within bounds.
|
||||
*/
|
||||
public final boolean isInBounds(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();
|
||||
long sizeInWords = (long) size * Constants.BYTES_PER_WORD;
|
||||
return start + sizeInWords <= this.buffer.capacity();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ final class WireHelpers {
|
|||
static boolean bounds_check(SegmentReader segment,
|
||||
int start,
|
||||
int size) {
|
||||
return segment == null || segment.in_bounds(start, size);
|
||||
return segment == null || segment.isInBounds(start, size);
|
||||
}
|
||||
|
||||
static class AllocateResult {
|
||||
|
|
|
@ -86,6 +86,34 @@ public class LayoutTest {
|
|||
StructReader reader = WireHelpers.readStructPointer(new BareStructReader(), arena.tryGetSegment(0), null, 0, null, 0, 0x7fffffff);
|
||||
}
|
||||
|
||||
|
||||
private static class BareListReader implements ListReader.Factory<ListReader> {
|
||||
BareListReader() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListReader constructReader(SegmentReader segment, int ptr, int elementCount, int step, int structDataSize, short structPointerCount, int nestingLimit) {
|
||||
return new ListReader(segment, ptr, elementCount, step, structDataSize, structPointerCount, nestingLimit);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = DecodeException.class)
|
||||
public void readListPointerShouldThrowDecodeExceptionOnOutOfBoundsCompositeListPointer() {
|
||||
byte[] brokenMSG = {
|
||||
// set list pointer bits to 1, elementSize to 7 to indicate composite list and number of words in the list (minus tag) to 0x1FFFFFFF (max value possible in 29b limit)
|
||||
0x01, 0x00, 0x00, 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,//tag with element wordSize of 1
|
||||
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);
|
||||
|
||||
ListReader reader = WireHelpers.readListPointer(new BareListReader(), arena.tryGetSegment(0), 0, null, 0, (byte) 0, 0x7fffffff);
|
||||
}
|
||||
|
||||
private class BareStructBuilder implements StructBuilder.Factory<StructBuilder> {
|
||||
private StructSize structSize;
|
||||
|
||||
|
|
18
runtime/src/test/java/org/capnproto/SegmentReaderTest.java
Normal file
18
runtime/src/test/java/org/capnproto/SegmentReaderTest.java
Normal file
|
@ -0,0 +1,18 @@
|
|||
package org.capnproto;
|
||||
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
|
||||
public class SegmentReaderTest {
|
||||
|
||||
@Test
|
||||
public void in_boundsCalculationShouldNotOverflow() {
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocate(64);
|
||||
SegmentReader segmentReader = new SegmentReader(byteBuffer, null);
|
||||
MatcherAssert.assertThat(segmentReader.isInBounds(0, Integer.MAX_VALUE), is(false));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue