Reject DHCP packets with no magic cookie

am: 006e061301

Change-Id: I54a32519d13e8d5463ca86630540722d73ff75cb
This commit is contained in:
Hugo Benichi
2016-10-07 02:29:49 +00:00
committed by android-build-merger
3 changed files with 58 additions and 2 deletions

View File

@@ -50,6 +50,8 @@ public final class DhcpErrorEvent implements Parcelable {
public static final int DHCP_INVALID_OPTION_LENGTH = makeErrorCode(DHCP_ERROR, 3);
public static final int DHCP_NO_MSG_TYPE = makeErrorCode(DHCP_ERROR, 4);
public static final int DHCP_UNKNOWN_MSG_TYPE = makeErrorCode(DHCP_ERROR, 5);
/** {@hide} */
public static final int DHCP_NO_COOKIE = makeErrorCode(DHCP_ERROR, 6);
public static final int BUFFER_UNDERFLOW = makeErrorCode(MISC_ERROR, 1);
public static final int RECEIVE_ERROR = makeErrorCode(MISC_ERROR, 2);

View File

@@ -895,8 +895,12 @@ abstract class DhcpPacket {
+ 64 // skip server host name (64 chars)
+ 128); // skip boot file name (128 chars)
int dhcpMagicCookie = packet.getInt();
// Ensure this is a DHCP packet with a magic cookie, and not BOOTP. http://b/31850211
if (packet.remaining() < 4) {
throw new ParseException(DhcpErrorEvent.DHCP_NO_COOKIE, "not a DHCP message");
}
int dhcpMagicCookie = packet.getInt();
if (dhcpMagicCookie != DHCP_MAGIC_COOKIE) {
throw new ParseException(DhcpErrorEvent.DHCP_BAD_MAGIC_COOKIE,
"Bad magic cookie 0x%08x, should be 0x%08x",

View File

@@ -27,6 +27,7 @@ import java.net.Inet4Address;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import junit.framework.TestCase;
import static android.net.dhcp.DhcpPacket.*;
@@ -430,7 +431,7 @@ public class DhcpPacketTest extends TestCase {
try {
DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
} catch (DhcpPacket.ParseException expected) {
assertDhcpErrorCodes(DhcpErrorEvent.PARSING_ERROR, expected.errorCode);
assertDhcpErrorCodes(DhcpErrorEvent.DHCP_NO_COOKIE, expected.errorCode);
return;
}
fail("Dhcp packet parsing should have failed");
@@ -472,6 +473,55 @@ public class DhcpPacketTest extends TestCase {
assertEquals(Integer.toHexString(expected), Integer.toHexString(got));
}
public void testTruncatedOfferPackets() throws Exception {
final byte[] packet = HexDump.hexStringToByteArray(
// IP header.
"450001518d0600004011144dc0a82b01c0a82bf7" +
// UDP header.
"00430044013d9ac7" +
// BOOTP header.
"02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
// MAC address.
"30766ff2a90c00000000000000000000" +
// Server name.
"0000000000000000000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000" +
// File.
"0000000000000000000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000" +
// Options
"638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
"1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff");
for (int len = 0; len < packet.length; len++) {
try {
DhcpPacket.decodeFullPacket(packet, len, ENCAP_L3);
} catch (ParseException e) {
if (e.errorCode == DhcpErrorEvent.PARSING_ERROR) {
fail(String.format("bad truncated packet of length %d", len));
}
}
}
}
public void testRandomPackets() throws Exception {
final int maxRandomPacketSize = 512;
final Random r = new Random();
for (int i = 0; i < 10000; i++) {
byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
r.nextBytes(packet);
try {
DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
} catch (ParseException e) {
if (e.errorCode == DhcpErrorEvent.PARSING_ERROR) {
fail("bad packet: " + HexDump.toHexString(packet));
}
}
}
}
private byte[] mtuBytes(int mtu) {
// 0x1a02: option 26, length 2. 0xff: no more options.
if (mtu > Short.MAX_VALUE - Short.MIN_VALUE) {