Skip to content

Commit 1b494c5

Browse files
committed
Avoid overflow in index input slices invariant checks (#14126)
This commit avoids overflow in index input slices invariant checks. While not a problem in practice, this can lead to more obscure failures which are harder to diagnose. Reworking the invariant checks to avoid the potential to overflow is trivial. Existing tests cover the most cases, while a single new scenario covered the overflow case.
1 parent e0458f8 commit 1b494c5

File tree

8 files changed

+15
-6
lines changed

8 files changed

+15
-6
lines changed

lucene/CHANGES.txt

+3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ Bug Fixes
5252

5353
* GITHUB#14123: SortingCodecReader NPE when segment has no (points, vectors, etc...) (Mike Sokolov)
5454

55+
* GITHUB#14126: Avoid overflow in index input slices invariant checks
56+
(Chris Hegarty)
57+
5558
Other
5659
---------------------
5760

lucene/core/src/java/org/apache/lucene/store/BufferedIndexInput.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ private static final class SlicedIndexInput extends BufferedIndexInput {
401401
? base.toString()
402402
: (base.toString() + " [slice=" + sliceDescription + "]"),
403403
BufferedIndexInput.BUFFER_SIZE);
404-
if (offset < 0 || length < 0 || offset + length > base.length()) {
404+
if ((length | offset) < 0 || length > base.length() - offset) {
405405
throw new IllegalArgumentException(
406406
"slice() " + sliceDescription + " out of bounds: " + base);
407407
}

lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataInput.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ public void skipBytes(long numBytes) throws IOException {
424424
}
425425

426426
public ByteBuffersDataInput slice(long offset, long length) {
427-
if (offset < 0 || length < 0 || offset + length > this.length) {
427+
if ((length | offset) < 0 || length > this.length - offset) {
428428
throw new IllegalArgumentException(
429429
String.format(
430430
Locale.ROOT,

lucene/core/src/java/org/apache/lucene/store/NIOFSDirectory.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public NIOFSIndexInput clone() {
139139

140140
@Override
141141
public IndexInput slice(String sliceDescription, long offset, long length) throws IOException {
142-
if (offset < 0 || length < 0 || offset + length > this.length()) {
142+
if ((length | offset) < 0 || length > this.length() - offset) {
143143
throw new IllegalArgumentException(
144144
"slice() "
145145
+ sliceDescription

lucene/core/src/java21/org/apache/lucene/store/MemorySegmentIndexInput.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ public final MemorySegmentIndexInput clone() {
597597
*/
598598
@Override
599599
public final MemorySegmentIndexInput slice(String sliceDescription, long offset, long length) {
600-
if (offset < 0 || length < 0 || offset + length > this.length) {
600+
if ((length | offset) < 0 || length > this.length - offset) {
601601
throw new IllegalArgumentException(
602602
"slice() "
603603
+ sliceDescription

lucene/misc/src/java/org/apache/lucene/misc/store/RAFDirectory.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public RAFIndexInput clone() {
136136

137137
@Override
138138
public IndexInput slice(String sliceDescription, long offset, long length) throws IOException {
139-
if (offset < 0 || length < 0 || offset + length > this.length()) {
139+
if ((length | offset) < 0 || length > this.length() - offset) {
140140
throw new IllegalArgumentException(
141141
"slice() " + sliceDescription + " out of bounds: " + this);
142142
}

lucene/test-framework/src/java/org/apache/lucene/tests/store/BaseDirectoryTestCase.java

+6
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,12 @@ public void testSliceOutOfBounds() throws Exception {
771771
slice.slice("slice3sub", 1, len / 2);
772772
});
773773

774+
expectThrows(
775+
IllegalArgumentException.class,
776+
() -> {
777+
i.slice("slice4", Long.MAX_VALUE - 1, 10);
778+
});
779+
774780
i.close();
775781
}
776782
}

lucene/test-framework/src/java/org/apache/lucene/tests/store/SerialIOCountingDirectory.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ public IndexInput slice(String sliceDescription, long offset, long length) throw
194194
public IndexInput slice(
195195
String sliceDescription, long offset, long length, ReadAdvice readAdvice)
196196
throws IOException {
197-
if (offset < 0 || offset + length > sliceLength) {
197+
if ((length | offset) < 0 || length > sliceLength - offset) {
198198
throw new IllegalArgumentException();
199199
}
200200
IndexInput clone = in.clone();

0 commit comments

Comments
 (0)