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

Commit 91723d7f authored by Paul Jensen's avatar Paul Jensen
Browse files

Avoid APF JNEBS instruction with R1 as it doesn't work

APF version 2 and prior versions fail to execute JNEBS with R1 argument.
The APF interpreter tries to use R1's value as the number of bytes to
compare, as well as the offset within the packet to compare at.
This change makes ApfFilter avoid using this and makes the APF generator
throw if this is used.  This was limiting the IPv4 filter, causing it to
only drop multicast (when multicast filtering was enabled), rather than
a wider range of broadcast packets.

Bug: 28206777

Change-Id: I8d116e024e8bd641b21053c6b1defc734d744467
parent c2e8857a
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@ public class ApfFilter {
    private static final boolean VDBG = false;

    private static final int ETH_HEADER_LEN = 14;
    private static final int ETH_DEST_ADDR_OFFSET = 0;
    private static final int ETH_ETHERTYPE_OFFSET = 12;
    private static final byte[] ETH_BROADCAST_MAC_ADDRESS = new byte[]{
            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
@@ -582,7 +583,6 @@ public class ApfFilter {
     * DROP_LABEL or PASS_LABEL and does not fall off the end.
     * Preconditions:
     *  - Packet being filtered is IPv4
     *  - R1 is initialized to 0
     */
    @GuardedBy("this")
    private void generateIPv4FilterLocked(ApfGenerator gen) throws IllegalInstructionException {
@@ -605,9 +605,8 @@ public class ApfFilter {

        // Drop all broadcasts besides DHCP addressed to us
        // If not a broadcast packet, pass
        // NOTE: Relies on R1 being initialized to 0 which is the offset of the ethernet
        //       destination MAC address
        gen.addJumpIfBytesNotEqual(Register.R1, ETH_BROADCAST_MAC_ADDRESS, gen.PASS_LABEL);
        gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
        gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, gen.PASS_LABEL);
        // If not UDP, drop
        gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET);
        gen.addJumpIfR0NotEquals(IPPROTO_UDP, gen.DROP_LABEL);
+5 −1
Original line number Diff line number Diff line
@@ -734,7 +734,11 @@ public class ApfGenerator {
     * Add an instruction to the end of the program to jump to {@code target} if the bytes of the
     * packet at, an offset specified by {@code register}, match {@code bytes}.
     */
    public ApfGenerator addJumpIfBytesNotEqual(Register register, byte[] bytes, String target) {
    public ApfGenerator addJumpIfBytesNotEqual(Register register, byte[] bytes, String target)
            throws IllegalInstructionException {
        if (register == Register.R1) {
            throw new IllegalInstructionException("JNEBS fails with R1");
        }
        Instruction instruction = new Instruction(Opcodes.JNEBS, register);
        instruction.setUnsignedImm(bytes.length);
        instruction.setTargetLabel(target);