Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ea2f7a4f authored by Hugo Benichi's avatar Hugo Benichi Committed by Android (Google) Code Review
Browse files

Merge "Reject DHCP packets with no magic cookie" into nyc-mr1-dev

parents 0fe683da 006e0613
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);
+5 −1
Original line number Diff line number Diff line
@@ -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",
+51 −1
Original line number Diff line number Diff line
@@ -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) {