HADOOP-8275. Range check DelegationKey length. Contributed by Colin Patrick McCabe
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1332839 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7d1b804d3a
commit
bbfda83044
@ -392,6 +392,9 @@ Release 2.0.0 - UNRELEASED
|
|||||||
HADOOP-8325. Add a ShutdownHookManager to be used by different
|
HADOOP-8325. Add a ShutdownHookManager to be used by different
|
||||||
components instead of the JVM shutdownhook (tucu)
|
components instead of the JVM shutdownhook (tucu)
|
||||||
|
|
||||||
|
HADOOP-8275. Range check DelegationKey length.
|
||||||
|
(Colin Patrick McCabe via eli)
|
||||||
|
|
||||||
BREAKDOWN OF HADOOP-7454 SUBTASKS
|
BREAKDOWN OF HADOOP-7454 SUBTASKS
|
||||||
|
|
||||||
HADOOP-7455. HA: Introduce HA Service Protocol Interface. (suresh)
|
HADOOP-7455. HA: Introduce HA Service Protocol Interface. (suresh)
|
||||||
|
@ -326,9 +326,41 @@ public static long readVLong(DataInput stream) throws IOException {
|
|||||||
* @return deserialized integer from stream.
|
* @return deserialized integer from stream.
|
||||||
*/
|
*/
|
||||||
public static int readVInt(DataInput stream) throws IOException {
|
public static int readVInt(DataInput stream) throws IOException {
|
||||||
return (int) readVLong(stream);
|
long n = readVLong(stream);
|
||||||
|
if ((n > Integer.MAX_VALUE) || (n < Integer.MIN_VALUE)) {
|
||||||
|
throw new IOException("value too long to fit in integer");
|
||||||
|
}
|
||||||
|
return (int)n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads an integer from the input stream and returns it.
|
||||||
|
*
|
||||||
|
* This function validates that the integer is between [lower, upper],
|
||||||
|
* inclusive.
|
||||||
|
*
|
||||||
|
* @param stream Binary input stream
|
||||||
|
* @throws java.io.IOException
|
||||||
|
* @return deserialized integer from stream
|
||||||
|
*/
|
||||||
|
public static int readVIntInRange(DataInput stream, int lower, int upper)
|
||||||
|
throws IOException {
|
||||||
|
long n = readVLong(stream);
|
||||||
|
if (n < lower) {
|
||||||
|
if (lower == 0) {
|
||||||
|
throw new IOException("expected non-negative integer, got " + n);
|
||||||
|
} else {
|
||||||
|
throw new IOException("expected integer greater than or equal to " +
|
||||||
|
lower + ", got " + n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n > upper) {
|
||||||
|
throw new IOException("expected integer less or equal to " + upper +
|
||||||
|
", got " + n);
|
||||||
|
}
|
||||||
|
return (int)n;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given the first byte of a vint/vlong, determine the sign
|
* Given the first byte of a vint/vlong, determine the sign
|
||||||
* @param value the first byte
|
* @param value the first byte
|
||||||
|
@ -41,6 +41,7 @@ public class DelegationKey implements Writable {
|
|||||||
private long expiryDate;
|
private long expiryDate;
|
||||||
@Nullable
|
@Nullable
|
||||||
private byte[] keyBytes = null;
|
private byte[] keyBytes = null;
|
||||||
|
private static final int MAX_KEY_LEN = 1024 * 1024;
|
||||||
|
|
||||||
/** Default constructore required for Writable */
|
/** Default constructore required for Writable */
|
||||||
public DelegationKey() {
|
public DelegationKey() {
|
||||||
@ -55,6 +56,10 @@ public DelegationKey(int keyId, long expiryDate, byte[] encodedKey) {
|
|||||||
this.keyId = keyId;
|
this.keyId = keyId;
|
||||||
this.expiryDate = expiryDate;
|
this.expiryDate = expiryDate;
|
||||||
if (encodedKey != null) {
|
if (encodedKey != null) {
|
||||||
|
if (encodedKey.length > MAX_KEY_LEN) {
|
||||||
|
throw new RuntimeException("can't create " + encodedKey.length +
|
||||||
|
" byte long DelegationKey.");
|
||||||
|
}
|
||||||
this.keyBytes = encodedKey;
|
this.keyBytes = encodedKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,7 +107,7 @@ public void write(DataOutput out) throws IOException {
|
|||||||
public void readFields(DataInput in) throws IOException {
|
public void readFields(DataInput in) throws IOException {
|
||||||
keyId = WritableUtils.readVInt(in);
|
keyId = WritableUtils.readVInt(in);
|
||||||
expiryDate = WritableUtils.readVLong(in);
|
expiryDate = WritableUtils.readVLong(in);
|
||||||
int len = WritableUtils.readVInt(in);
|
int len = WritableUtils.readVIntInRange(in, -1, MAX_KEY_LEN);
|
||||||
if (len == -1) {
|
if (len == -1) {
|
||||||
keyBytes = null;
|
keyBytes = null;
|
||||||
} else {
|
} else {
|
||||||
|
@ -44,6 +44,26 @@ public static void testValue(int val, int vintlen) throws IOException {
|
|||||||
assertEquals(vintlen, WritableUtils.getVIntSize(val));
|
assertEquals(vintlen, WritableUtils.getVIntSize(val));
|
||||||
assertEquals(vintlen, WritableUtils.decodeVIntSize(buf.getData()[0]));
|
assertEquals(vintlen, WritableUtils.decodeVIntSize(buf.getData()[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void testReadInRange(long val, int lower,
|
||||||
|
int upper, boolean expectSuccess) throws IOException {
|
||||||
|
DataOutputBuffer buf = new DataOutputBuffer();
|
||||||
|
DataInputBuffer inbuf = new DataInputBuffer();
|
||||||
|
WritableUtils.writeVLong(buf, val);
|
||||||
|
try {
|
||||||
|
inbuf.reset(buf.getData(), 0, buf.getLength());
|
||||||
|
long val2 = WritableUtils.readVIntInRange(inbuf, lower, upper);
|
||||||
|
if (!expectSuccess) {
|
||||||
|
fail("expected readVIntInRange to throw an exception");
|
||||||
|
}
|
||||||
|
assertEquals(val, val2);
|
||||||
|
} catch(IOException e) {
|
||||||
|
if (expectSuccess) {
|
||||||
|
LOG.error("unexpected exception:", e);
|
||||||
|
fail("readVIntInRange threw an unexpected exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void testVInt() throws Exception {
|
public static void testVInt() throws Exception {
|
||||||
testValue(12, 1);
|
testValue(12, 1);
|
||||||
@ -61,5 +81,10 @@ public static void testVInt() throws Exception {
|
|||||||
testValue(-65536, 3);
|
testValue(-65536, 3);
|
||||||
testValue(65536, 4);
|
testValue(65536, 4);
|
||||||
testValue(-65537, 4);
|
testValue(-65537, 4);
|
||||||
|
testReadInRange(123, 122, 123, true);
|
||||||
|
testReadInRange(123, 0, 100, false);
|
||||||
|
testReadInRange(0, 0, 100, true);
|
||||||
|
testReadInRange(-1, 0, 100, false);
|
||||||
|
testReadInRange(1099511627776L, 0, Integer.MAX_VALUE, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user