提交 2f63ffc9 编写于 作者: V valeriep

8022927: Input validation for byte/endian conversions

Summary: Add additional boundary checks
Reviewed-by: ascarpino
上级 335a20a4
/* /*
* Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -43,10 +43,8 @@ import sun.misc.Unsafe; ...@@ -43,10 +43,8 @@ import sun.misc.Unsafe;
* These are the only platforms we currently support, but other optimized * These are the only platforms we currently support, but other optimized
* variants could be added as needed. * variants could be added as needed.
* *
* NOTE that because this code performs unchecked direct memory access, it * NOTE that ArrayIndexOutOfBoundsException will be thrown if the bounds checks
* MUST be restricted to trusted code. It is imperative that the caller protects * failed.
* against out of bounds memory access by performing the necessary bounds
* checks before calling methods in this class.
* *
* This class may also be helpful in improving the performance of the * This class may also be helpful in improving the performance of the
* crypto code in the SunJCE provider. However, for now it is only accessible by * crypto code in the SunJCE provider. However, for now it is only accessible by
...@@ -103,6 +101,10 @@ final class ByteArrayAccess { ...@@ -103,6 +101,10 @@ final class ByteArrayAccess {
* byte[] to int[] conversion, little endian byte order. * byte[] to int[] conversion, little endian byte order.
*/ */
static void b2iLittle(byte[] in, int inOfs, int[] out, int outOfs, int len) { static void b2iLittle(byte[] in, int inOfs, int[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len) ||
(outOfs < 0) || ((out.length - outOfs) < len/4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) { if (littleEndianUnaligned) {
inOfs += byteArrayOfs; inOfs += byteArrayOfs;
len += inOfs; len += inOfs;
...@@ -131,6 +133,10 @@ final class ByteArrayAccess { ...@@ -131,6 +133,10 @@ final class ByteArrayAccess {
// Special optimization of b2iLittle(in, inOfs, out, 0, 64) // Special optimization of b2iLittle(in, inOfs, out, 0, 64)
static void b2iLittle64(byte[] in, int inOfs, int[] out) { static void b2iLittle64(byte[] in, int inOfs, int[] out) {
if ((inOfs < 0) || ((in.length - inOfs) < 64) ||
(out.length < 16)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) { if (littleEndianUnaligned) {
inOfs += byteArrayOfs; inOfs += byteArrayOfs;
out[ 0] = unsafe.getInt(in, (long)(inOfs )); out[ 0] = unsafe.getInt(in, (long)(inOfs ));
...@@ -176,6 +182,10 @@ final class ByteArrayAccess { ...@@ -176,6 +182,10 @@ final class ByteArrayAccess {
* int[] to byte[] conversion, little endian byte order. * int[] to byte[] conversion, little endian byte order.
*/ */
static void i2bLittle(int[] in, int inOfs, byte[] out, int outOfs, int len) { static void i2bLittle(int[] in, int inOfs, byte[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len/4) ||
(outOfs < 0) || ((out.length - outOfs) < len)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) { if (littleEndianUnaligned) {
outOfs += byteArrayOfs; outOfs += byteArrayOfs;
len += outOfs; len += outOfs;
...@@ -204,6 +214,9 @@ final class ByteArrayAccess { ...@@ -204,6 +214,9 @@ final class ByteArrayAccess {
// Store one 32-bit value into out[outOfs..outOfs+3] in little endian order. // Store one 32-bit value into out[outOfs..outOfs+3] in little endian order.
static void i2bLittle4(int val, byte[] out, int outOfs) { static void i2bLittle4(int val, byte[] out, int outOfs) {
if ((outOfs < 0) || ((out.length - outOfs) < 4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) { if (littleEndianUnaligned) {
unsafe.putInt(out, (long)(byteArrayOfs + outOfs), val); unsafe.putInt(out, (long)(byteArrayOfs + outOfs), val);
} else if (bigEndian && ((outOfs & 3) == 0)) { } else if (bigEndian && ((outOfs & 3) == 0)) {
...@@ -220,6 +233,10 @@ final class ByteArrayAccess { ...@@ -220,6 +233,10 @@ final class ByteArrayAccess {
* byte[] to int[] conversion, big endian byte order. * byte[] to int[] conversion, big endian byte order.
*/ */
static void b2iBig(byte[] in, int inOfs, int[] out, int outOfs, int len) { static void b2iBig(byte[] in, int inOfs, int[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len) ||
(outOfs < 0) || ((out.length - outOfs) < len/4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) { if (littleEndianUnaligned) {
inOfs += byteArrayOfs; inOfs += byteArrayOfs;
len += inOfs; len += inOfs;
...@@ -248,6 +265,10 @@ final class ByteArrayAccess { ...@@ -248,6 +265,10 @@ final class ByteArrayAccess {
// Special optimization of b2iBig(in, inOfs, out, 0, 64) // Special optimization of b2iBig(in, inOfs, out, 0, 64)
static void b2iBig64(byte[] in, int inOfs, int[] out) { static void b2iBig64(byte[] in, int inOfs, int[] out) {
if ((inOfs < 0) || ((in.length - inOfs) < 64) ||
(out.length < 16)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) { if (littleEndianUnaligned) {
inOfs += byteArrayOfs; inOfs += byteArrayOfs;
out[ 0] = reverseBytes(unsafe.getInt(in, (long)(inOfs ))); out[ 0] = reverseBytes(unsafe.getInt(in, (long)(inOfs )));
...@@ -293,6 +314,10 @@ final class ByteArrayAccess { ...@@ -293,6 +314,10 @@ final class ByteArrayAccess {
* int[] to byte[] conversion, big endian byte order. * int[] to byte[] conversion, big endian byte order.
*/ */
static void i2bBig(int[] in, int inOfs, byte[] out, int outOfs, int len) { static void i2bBig(int[] in, int inOfs, byte[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len/4) ||
(outOfs < 0) || ((out.length - outOfs) < len)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) { if (littleEndianUnaligned) {
outOfs += byteArrayOfs; outOfs += byteArrayOfs;
len += outOfs; len += outOfs;
...@@ -321,6 +346,9 @@ final class ByteArrayAccess { ...@@ -321,6 +346,9 @@ final class ByteArrayAccess {
// Store one 32-bit value into out[outOfs..outOfs+3] in big endian order. // Store one 32-bit value into out[outOfs..outOfs+3] in big endian order.
static void i2bBig4(int val, byte[] out, int outOfs) { static void i2bBig4(int val, byte[] out, int outOfs) {
if ((outOfs < 0) || ((out.length - outOfs) < 4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) { if (littleEndianUnaligned) {
unsafe.putInt(out, (long)(byteArrayOfs + outOfs), reverseBytes(val)); unsafe.putInt(out, (long)(byteArrayOfs + outOfs), reverseBytes(val));
} else if (bigEndian && ((outOfs & 3) == 0)) { } else if (bigEndian && ((outOfs & 3) == 0)) {
...@@ -337,6 +365,10 @@ final class ByteArrayAccess { ...@@ -337,6 +365,10 @@ final class ByteArrayAccess {
* byte[] to long[] conversion, big endian byte order. * byte[] to long[] conversion, big endian byte order.
*/ */
static void b2lBig(byte[] in, int inOfs, long[] out, int outOfs, int len) { static void b2lBig(byte[] in, int inOfs, long[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len) ||
(outOfs < 0) || ((out.length - outOfs) < len/8)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) { if (littleEndianUnaligned) {
inOfs += byteArrayOfs; inOfs += byteArrayOfs;
len += inOfs; len += inOfs;
...@@ -378,6 +410,10 @@ final class ByteArrayAccess { ...@@ -378,6 +410,10 @@ final class ByteArrayAccess {
// Special optimization of b2lBig(in, inOfs, out, 0, 128) // Special optimization of b2lBig(in, inOfs, out, 0, 128)
static void b2lBig128(byte[] in, int inOfs, long[] out) { static void b2lBig128(byte[] in, int inOfs, long[] out) {
if ((inOfs < 0) || ((in.length - inOfs) < 128) ||
(out.length < 16)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) { if (littleEndianUnaligned) {
inOfs += byteArrayOfs; inOfs += byteArrayOfs;
out[ 0] = reverseBytes(unsafe.getLong(in, (long)(inOfs ))); out[ 0] = reverseBytes(unsafe.getLong(in, (long)(inOfs )));
...@@ -406,6 +442,10 @@ final class ByteArrayAccess { ...@@ -406,6 +442,10 @@ final class ByteArrayAccess {
* long[] to byte[] conversion, big endian byte order. * long[] to byte[] conversion, big endian byte order.
*/ */
static void l2bBig(long[] in, int inOfs, byte[] out, int outOfs, int len) { static void l2bBig(long[] in, int inOfs, byte[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len/8) ||
(outOfs < 0) || ((out.length - outOfs) < len)) {
throw new ArrayIndexOutOfBoundsException();
}
len += outOfs; len += outOfs;
while (outOfs < len) { while (outOfs < len) {
long i = in[inOfs++]; long i = in[inOfs++];
...@@ -419,5 +459,4 @@ final class ByteArrayAccess { ...@@ -419,5 +459,4 @@ final class ByteArrayAccess {
out[outOfs++] = (byte)(i ); out[outOfs++] = (byte)(i );
} }
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册