Skip to content

Commit 7e20d5b

Browse files
authored
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 dce24c8 commit 7e20d5b

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
@@ -84,6 +84,9 @@ Bug Fixes
8484

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

87+
* GITHUB#14126: Avoid overflow in index input slices invariant checks
88+
(Chris Hegarty)
89+
8790
Other
8891
---------------------
8992

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)