Merge \"Don\'t loop forever on 0-length options.\" into nyc-dev

am: 7aac630f8e

Change-Id: I188441196255ffe132adef00728502101199756b
This commit is contained in:
Lorenzo Colitti
2016-06-23 08:18:03 +00:00
committed by android-build-merger
2 changed files with 28 additions and 2 deletions

View File

@@ -367,8 +367,9 @@ public class ApfFilter {
} }
// Note that this parses RA and may throw IllegalArgumentException (from // Note that this parses RA and may throw IllegalArgumentException (from
// Buffer.position(int) ) or IndexOutOfBoundsException (from ByteBuffer.get(int) ) if // Buffer.position(int) or due to an invalid-length option) or IndexOutOfBoundsException
// parsing encounters something non-compliant with specifications. // (from ByteBuffer.get(int) ) if parsing encounters something non-compliant with
// specifications.
Ra(byte[] packet, int length) { Ra(byte[] packet, int length) {
mPacket = ByteBuffer.allocate(length).put(ByteBuffer.wrap(packet, 0, length)); mPacket = ByteBuffer.allocate(length).put(ByteBuffer.wrap(packet, 0, length));
mPacket.clear(); mPacket.clear();
@@ -418,6 +419,10 @@ public class ApfFilter {
// compatibility. // compatibility.
break; break;
} }
if (optionLength <= 0) {
throw new IllegalArgumentException(String.format(
"Invalid option length opt=%d len=%d", optionType, optionLength));
}
mPacket.position(mPacket.position() + optionLength); mPacket.position(mPacket.position() + optionLength);
} }
// Mark non-lifetime bytes since last lifetime. // Mark non-lifetime bytes since last lifetime.

View File

@@ -552,6 +552,10 @@ public class ApfTest extends AndroidTestCase {
assertTrue(mGotApfProgram.block(TIMEOUT_MS)); assertTrue(mGotApfProgram.block(TIMEOUT_MS));
return mLastApfProgram; return mLastApfProgram;
} }
public void assertNoProgramUpdate() {
assertFalse(mGotApfProgram.block(TIMEOUT_MS));
}
} }
private static class TestApfFilter extends ApfFilter { private static class TestApfFilter extends ApfFilter {
@@ -863,6 +867,13 @@ public class ApfTest extends AndroidTestCase {
verifyRaLifetime(ipManagerCallback, packet, lifetime); verifyRaLifetime(ipManagerCallback, packet, lifetime);
} }
private void assertInvalidRa(TestApfFilter apfFilter, MockIpManagerCallback ipManagerCallback,
ByteBuffer packet) throws IOException, ErrnoException {
ipManagerCallback.resetApfProgramWait();
apfFilter.pretendPacketReceived(packet.array());
ipManagerCallback.assertNoProgramUpdate();
}
@LargeTest @LargeTest
public void testApfFilterRa() throws Exception { public void testApfFilterRa() throws Exception {
MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
@@ -881,6 +892,16 @@ public class ApfTest extends AndroidTestCase {
testRaLifetime(apfFilter, ipManagerCallback, basePacket, 1000); testRaLifetime(apfFilter, ipManagerCallback, basePacket, 1000);
// Ensure zero-length options cause the packet to be silently skipped.
// Do this before we test other packets. http://b/29586253
ByteBuffer zeroLengthOptionPacket = ByteBuffer.wrap(
new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
basePacket.clear();
zeroLengthOptionPacket.put(basePacket);
zeroLengthOptionPacket.put((byte)ICMP6_PREFIX_OPTION_TYPE);
zeroLengthOptionPacket.put((byte)0);
assertInvalidRa(apfFilter, ipManagerCallback, zeroLengthOptionPacket);
// Generate several RAs with different options and lifetimes, and verify when // Generate several RAs with different options and lifetimes, and verify when
// ApfFilter is shown these packets, it generates programs to filter them for the // ApfFilter is shown these packets, it generates programs to filter them for the
// appropriate lifetime. // appropriate lifetime.