diff options
| author | 2018-04-19 07:25:11 -0700 | |
|---|---|---|
| committer | 2018-04-19 07:25:11 -0700 | |
| commit | e56afce9e95b27a9ee53b4fa6938cb3421e600e8 (patch) | |
| tree | d98588b50a5d74026000f26d610e25fa0a73ef7e | |
| parent | 5124d28e64c6da5f807de136a70b2f168e885022 (diff) | |
| parent | 05011abf27f1d16ea813952318d56cd2e7cc462e (diff) | |
Merge "Adjust APF interpreter tests to match APFv4"
am: 05011abf27
Change-Id: I5ca2b41ab6c101bef7465229270079c81743c757
| -rw-r--r-- | services/net/java/android/net/apf/ApfGenerator.java | 12 | ||||
| -rw-r--r-- | tests/net/java/android/net/apf/ApfTest.java | 34 | ||||
| -rw-r--r-- | tests/net/jni/apf_jni.cpp | 21 |
3 files changed, 42 insertions, 25 deletions
diff --git a/services/net/java/android/net/apf/ApfGenerator.java b/services/net/java/android/net/apf/ApfGenerator.java index fcfb19ce5a68..99b2fc6db472 100644 --- a/services/net/java/android/net/apf/ApfGenerator.java +++ b/services/net/java/android/net/apf/ApfGenerator.java @@ -841,30 +841,30 @@ public class ApfGenerator { /** * Add an instruction to the end of the program to load 32 bits from the data memory into - * {@code register}. The source address is computed by adding @{code offset} to the other - * register. + * {@code register}. The source address is computed by adding the signed immediate + * @{code offset} to the other register. * Requires APF v3 or greater. */ public ApfGenerator addLoadData(Register destinationRegister, int offset) throws IllegalInstructionException { requireApfVersion(3); Instruction instruction = new Instruction(Opcodes.LDDW, destinationRegister); - instruction.setUnsignedImm(offset); + instruction.setSignedImm(offset); addInstruction(instruction); return this; } /** * Add an instruction to the end of the program to store 32 bits from {@code register} into the - * data memory. The destination address is computed by adding @{code offset} to the other - * register. + * data memory. The destination address is computed by adding the signed immediate + * @{code offset} to the other register. * Requires APF v3 or greater. */ public ApfGenerator addStoreData(Register sourceRegister, int offset) throws IllegalInstructionException { requireApfVersion(3); Instruction instruction = new Instruction(Opcodes.STDW, sourceRegister); - instruction.setUnsignedImm(offset); + instruction.setSignedImm(offset); addInstruction(instruction); return this; } diff --git a/tests/net/java/android/net/apf/ApfTest.java b/tests/net/java/android/net/apf/ApfTest.java index 082f3108ed0a..f8a413226bd2 100644 --- a/tests/net/java/android/net/apf/ApfTest.java +++ b/tests/net/java/android/net/apf/ApfTest.java @@ -160,7 +160,7 @@ public class ApfTest { throw new Exception( "program: " + HexDump.toHexString(program) + "\ndata memory: " + HexDump.toHexString(data) + - "\nexpected: " + HexDump.toHexString(expected_data)); + "\nexpected: " + HexDump.toHexString(expected_data)); } } @@ -625,18 +625,19 @@ public class ApfTest { @Test public void testApfDataWrite() throws IllegalInstructionException, Exception { byte[] packet = new byte[MIN_PKT_SIZE]; - byte[] data = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; + byte[] data = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; byte[] expected_data = data.clone(); // No memory access instructions: should leave the data segment untouched. ApfGenerator gen = new ApfGenerator(3); assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data); - // Expect value 0x87654321 to be stored starting from address 3 + 2, in big-endian order. + // Expect value 0x87654321 to be stored starting from address -11 from the end of the + // data buffer, in big-endian order. gen = new ApfGenerator(3); gen.addLoadImmediate(Register.R0, 0x87654321); - gen.addLoadImmediate(Register.R1, 2); - gen.addStoreData(Register.R0, 3); + gen.addLoadImmediate(Register.R1, -5); + gen.addStoreData(Register.R0, -6); // -5 + -6 = -11 (offset +5 with data_len=16) expected_data[5] = (byte)0x87; expected_data[6] = (byte)0x65; expected_data[7] = (byte)0x43; @@ -646,16 +647,16 @@ public class ApfTest { @Test public void testApfDataRead() throws IllegalInstructionException, Exception { - // Program that DROPs if address 11 (7 + 3) contains 0x87654321. + // Program that DROPs if address 10 (-6) contains 0x87654321. ApfGenerator gen = new ApfGenerator(3); - gen.addLoadImmediate(Register.R1, 3); - gen.addLoadData(Register.R0, 7); + gen.addLoadImmediate(Register.R1, 10); + gen.addLoadData(Register.R0, -16); // 10 + -16 = -6 (offset +10 with data_len=16) gen.addJumpIfR0Equals(0x87654321, gen.DROP_LABEL); byte[] program = gen.generate(); byte[] packet = new byte[MIN_PKT_SIZE]; // Content is incorrect (last byte does not match) -> PASS - byte[] data = new byte[32]; + byte[] data = new byte[16]; data[10] = (byte)0x87; data[11] = (byte)0x65; data[12] = (byte)0x43; @@ -672,10 +673,10 @@ public class ApfTest { @Test public void testApfDataReadModifyWrite() throws IllegalInstructionException, Exception { ApfGenerator gen = new ApfGenerator(3); - gen.addLoadImmediate(Register.R1, 3); - gen.addLoadData(Register.R0, 7); // Load from address 7 + 3 = 10 + gen.addLoadImmediate(Register.R1, -22); + gen.addLoadData(Register.R0, 0); // Load from address 32 -22 + 0 = 10 gen.addAdd(0x78453412); // 87654321 + 78453412 = FFAA7733 - gen.addStoreData(Register.R0, 11); // Write back to address 11 + 3 = 14 + gen.addStoreData(Register.R0, 4); // Write back to address 32 -22 + 4 = 14 byte[] packet = new byte[MIN_PKT_SIZE]; byte[] data = new byte[32]; @@ -718,10 +719,17 @@ public class ApfTest { gen.addJump(gen.DROP_LABEL); assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data); - // ...but underflowing isn't allowed. + // ...and underflowing simply wraps around to the end of the buffer... gen = new ApfGenerator(3); gen.addLoadImmediate(Register.R0, 20); gen.addLoadData(Register.R1, -30); + gen.addJump(gen.DROP_LABEL); + assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data); + + // ...but doesn't allow accesses before the start of the buffer + gen = new ApfGenerator(3); + gen.addLoadImmediate(Register.R0, 20); + gen.addLoadData(Register.R1, -1000); gen.addJump(gen.DROP_LABEL); // Not reached. assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data); } diff --git a/tests/net/jni/apf_jni.cpp b/tests/net/jni/apf_jni.cpp index 79444e3f5ba8..1ea9e274ab9e 100644 --- a/tests/net/jni/apf_jni.cpp +++ b/tests/net/jni/apf_jni.cpp @@ -36,11 +36,20 @@ static jint com_android_server_ApfTest_apfSimulate( uint32_t program_len = env->GetArrayLength(program); uint32_t packet_len = env->GetArrayLength(packet); uint32_t data_len = data ? env->GetArrayLength(data) : 0; - jint result = accept_packet(program_raw, program_len, packet_raw, - packet_len, data_raw, data_len, filter_age); + + // Merge program and data into a single buffer. + uint8_t* program_and_data = (uint8_t*)malloc(program_len + data_len); + memcpy(program_and_data, program_raw, program_len); + memcpy(program_and_data + program_len, data_raw, data_len); + + jint result = + accept_packet(program_and_data, program_len, program_len + data_len, + packet_raw, packet_len, filter_age); if (data) { + memcpy(data_raw, program_and_data + program_len, data_len); env->ReleaseByteArrayElements(data, (jbyte*)data_raw, 0 /* copy back */); } + free(program_and_data); env->ReleaseByteArrayElements(packet, (jbyte*)packet_raw, JNI_ABORT); env->ReleaseByteArrayElements(program, (jbyte*)program_raw, JNI_ABORT); return result; @@ -109,8 +118,8 @@ static jboolean com_android_server_ApfTest_compareBpfApf(JNIEnv* env, jclass, js jstring jpcap_filename, jbyteArray japf_program) { ScopedUtfChars filter(env, jfilter); ScopedUtfChars pcap_filename(env, jpcap_filename); - const uint8_t* apf_program = (uint8_t*)env->GetByteArrayElements(japf_program, NULL); - const uint32_t apf_program_len = env->GetArrayLength(japf_program); + uint8_t* apf_program = (uint8_t*)env->GetByteArrayElements(japf_program, NULL); + uint32_t apf_program_len = env->GetArrayLength(japf_program); // Open pcap file for BPF filtering ScopedFILE bpf_fp(fopen(pcap_filename.c_str(), "rb")); @@ -152,8 +161,8 @@ static jboolean com_android_server_ApfTest_compareBpfApf(JNIEnv* env, jclass, js do { apf_packet = pcap_next(apf_pcap.get(), &apf_header); } while (apf_packet != NULL && !accept_packet( - apf_program, apf_program_len, apf_packet, apf_header.len, - nullptr, 0, 0)); + apf_program, apf_program_len, 0 /* data_len */, + apf_packet, apf_header.len, 0 /* filter_age */)); // Make sure both filters matched the same packet. if (apf_packet == NULL && bpf_packet == NULL) |