From d50908e7e0df12c891af64944b11b9c0fca7740f Mon Sep 17 00:00:00 2001 From: ChrisHegarty Date: Thu, 9 Jan 2025 17:28:49 +0000 Subject: [PATCH 1/2] Avoid overflow in index input slices invariant checks --- .../java/org/apache/lucene/store/BufferedIndexInput.java | 2 +- .../java/org/apache/lucene/store/ByteBuffersDataInput.java | 2 +- .../src/java/org/apache/lucene/store/NIOFSDirectory.java | 2 +- .../org/apache/lucene/store/MemorySegmentIndexInput.java | 2 +- .../src/java/org/apache/lucene/misc/store/RAFDirectory.java | 2 +- .../apache/lucene/tests/store/BaseDirectoryTestCase.java | 6 ++++++ .../lucene/tests/store/SerialIOCountingDirectory.java | 2 +- 7 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lucene/core/src/java/org/apache/lucene/store/BufferedIndexInput.java b/lucene/core/src/java/org/apache/lucene/store/BufferedIndexInput.java index 1738259fa2fb..cd47500a2df7 100644 --- a/lucene/core/src/java/org/apache/lucene/store/BufferedIndexInput.java +++ b/lucene/core/src/java/org/apache/lucene/store/BufferedIndexInput.java @@ -401,7 +401,7 @@ private static final class SlicedIndexInput extends BufferedIndexInput { ? base.toString() : (base.toString() + " [slice=" + sliceDescription + "]"), BufferedIndexInput.BUFFER_SIZE); - if (offset < 0 || length < 0 || offset + length > base.length()) { + if ((length | offset) < 0 || length > base.length() - offset) { throw new IllegalArgumentException( "slice() " + sliceDescription + " out of bounds: " + base); } diff --git a/lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataInput.java b/lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataInput.java index 39e920616209..dee5c8e3a738 100644 --- a/lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataInput.java +++ b/lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataInput.java @@ -424,7 +424,7 @@ public void skipBytes(long numBytes) throws IOException { } public ByteBuffersDataInput slice(long offset, long length) { - if (offset < 0 || length < 0 || offset + length > this.length) { + if ((length | offset) < 0 || length > this.length - offset) { throw new IllegalArgumentException( String.format( Locale.ROOT, diff --git a/lucene/core/src/java/org/apache/lucene/store/NIOFSDirectory.java b/lucene/core/src/java/org/apache/lucene/store/NIOFSDirectory.java index 246f48082cfe..bb2c5b5fe39e 100644 --- a/lucene/core/src/java/org/apache/lucene/store/NIOFSDirectory.java +++ b/lucene/core/src/java/org/apache/lucene/store/NIOFSDirectory.java @@ -139,7 +139,7 @@ public NIOFSIndexInput clone() { @Override public IndexInput slice(String sliceDescription, long offset, long length) throws IOException { - if (offset < 0 || length < 0 || offset + length > this.length()) { + if ((length | offset) < 0 || length > this.length() - offset) { throw new IllegalArgumentException( "slice() " + sliceDescription diff --git a/lucene/core/src/java21/org/apache/lucene/store/MemorySegmentIndexInput.java b/lucene/core/src/java21/org/apache/lucene/store/MemorySegmentIndexInput.java index 74594be5ec99..800a66a2167e 100644 --- a/lucene/core/src/java21/org/apache/lucene/store/MemorySegmentIndexInput.java +++ b/lucene/core/src/java21/org/apache/lucene/store/MemorySegmentIndexInput.java @@ -597,7 +597,7 @@ public final MemorySegmentIndexInput clone() { */ @Override public final MemorySegmentIndexInput slice(String sliceDescription, long offset, long length) { - if (offset < 0 || length < 0 || offset + length > this.length) { + if ((length | offset) < 0 || length > this.length - offset) { throw new IllegalArgumentException( "slice() " + sliceDescription diff --git a/lucene/misc/src/java/org/apache/lucene/misc/store/RAFDirectory.java b/lucene/misc/src/java/org/apache/lucene/misc/store/RAFDirectory.java index 420d6d40d6de..cd90db9abbe7 100644 --- a/lucene/misc/src/java/org/apache/lucene/misc/store/RAFDirectory.java +++ b/lucene/misc/src/java/org/apache/lucene/misc/store/RAFDirectory.java @@ -136,7 +136,7 @@ public RAFIndexInput clone() { @Override public IndexInput slice(String sliceDescription, long offset, long length) throws IOException { - if (offset < 0 || length < 0 || offset + length > this.length()) { + if ((length | offset) < 0 || length > this.length() - offset) { throw new IllegalArgumentException( "slice() " + sliceDescription + " out of bounds: " + this); } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/store/BaseDirectoryTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/store/BaseDirectoryTestCase.java index 6defa5eb8c7a..88223a4abebe 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/store/BaseDirectoryTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/store/BaseDirectoryTestCase.java @@ -771,6 +771,12 @@ public void testSliceOutOfBounds() throws Exception { slice.slice("slice3sub", 1, len / 2); }); + expectThrows( + IllegalArgumentException.class, + () -> { + i.slice("slice4", Long.MAX_VALUE - 1, 10); + }); + i.close(); } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/store/SerialIOCountingDirectory.java b/lucene/test-framework/src/java/org/apache/lucene/tests/store/SerialIOCountingDirectory.java index 1b4234c3d79f..4d3c233257c8 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/store/SerialIOCountingDirectory.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/store/SerialIOCountingDirectory.java @@ -194,7 +194,7 @@ public IndexInput slice(String sliceDescription, long offset, long length) throw public IndexInput slice( String sliceDescription, long offset, long length, ReadAdvice readAdvice) throws IOException { - if (offset < 0 || offset + length > sliceLength) { + if ((length | offset) < 0 || length > sliceLength - offset) { throw new IllegalArgumentException(); } IndexInput clone = in.clone(); From eb57712d317e012816648a75521b90804be6666a Mon Sep 17 00:00:00 2001 From: ChrisHegarty Date: Mon, 20 Jan 2025 09:04:50 +0000 Subject: [PATCH 2/2] changes --- lucene/CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index c2b37a94f895..39d7403a11c4 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -84,6 +84,9 @@ Bug Fixes * GITHUB#14123: SortingCodecReader NPE when segment has no (points, vectors, etc...) (Mike Sokolov) +* GITHUB#14126: Avoid overflow in index input slices invariant checks + (Chris Hegarty) + Other ---------------------