memtag_test: move SEGV code checks to device-side binary
parent
a3bf742c3e
commit
4756716904
|
@ -204,54 +204,63 @@ u8* alloc_default() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile u8 u8_var;
|
int expected_segv_code;
|
||||||
|
|
||||||
|
#define expect_segv(exp, segv_code) ({\
|
||||||
|
expected_segv_code = segv_code; \
|
||||||
|
volatile auto val = exp; \
|
||||||
|
(void) val; \
|
||||||
|
do_context_switch(); \
|
||||||
|
fprintf(stderr, "didn't receive SEGV code %i", segv_code); \
|
||||||
|
exit(1); })
|
||||||
|
|
||||||
|
// it's expected that the device is configured to use asymm MTE tag checking mode (sync read checks,
|
||||||
|
// async write checks)
|
||||||
|
#define expect_read_segv(exp) expect_segv(exp, SEGV_MTESERR)
|
||||||
|
#define expect_write_segv(exp) expect_segv(exp, SEGV_MTEAERR)
|
||||||
|
|
||||||
void read_after_free() {
|
void read_after_free() {
|
||||||
u8 *p = alloc_default();
|
u8 *p = alloc_default();
|
||||||
free(p);
|
free(p);
|
||||||
volatile u8 v = p[0];
|
expect_read_segv(p[0]);
|
||||||
(void) v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_after_free() {
|
void write_after_free() {
|
||||||
u8 *p = alloc_default();
|
u8 *p = alloc_default();
|
||||||
free(p);
|
free(p);
|
||||||
p[0] = 1;
|
expect_write_segv(p[0] = 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void underflow_read() {
|
void underflow_read() {
|
||||||
u8 *p = alloc_default();
|
u8 *p = alloc_default();
|
||||||
volatile u8 v = p[-1];
|
expect_read_segv(p[-1]);
|
||||||
(void) v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void underflow_write() {
|
void underflow_write() {
|
||||||
u8 *p = alloc_default();
|
u8 *p = alloc_default();
|
||||||
p[-1] = 1;
|
expect_write_segv(p[-1] = 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void overflow_read() {
|
void overflow_read() {
|
||||||
u8 *p = alloc_default();
|
u8 *p = alloc_default();
|
||||||
volatile u8 v = p[DEFAULT_ALLOC_SIZE + CANARY_SIZE];
|
expect_read_segv(p[DEFAULT_ALLOC_SIZE + CANARY_SIZE]);
|
||||||
(void) v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void overflow_write() {
|
void overflow_write() {
|
||||||
u8 *p = alloc_default();
|
u8 *p = alloc_default();
|
||||||
p[DEFAULT_ALLOC_SIZE + CANARY_SIZE] = 1;
|
expect_write_segv(p[DEFAULT_ALLOC_SIZE + CANARY_SIZE] = 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void untagged_read() {
|
void untagged_read() {
|
||||||
u8 *p = alloc_default();
|
u8 *p = alloc_default();
|
||||||
p = (u8 *) untag_pointer(p);
|
p = (u8 *) untag_pointer(p);
|
||||||
volatile u8 v = p[0];
|
expect_read_segv(p[0]);
|
||||||
(void) v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void untagged_write() {
|
void untagged_write() {
|
||||||
u8 *p = alloc_default();
|
u8 *p = alloc_default();
|
||||||
p = (u8 *) untag_pointer(p);
|
p = (u8 *) untag_pointer(p);
|
||||||
p[0] = 1;
|
expect_write_segv(p[0] = 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
map<string, function<void()>> tests = {
|
map<string, function<void()>> tests = {
|
||||||
|
@ -269,8 +278,12 @@ map<string, function<void()>> tests = {
|
||||||
};
|
};
|
||||||
|
|
||||||
void segv_handler(int, siginfo_t *si, void *) {
|
void segv_handler(int, siginfo_t *si, void *) {
|
||||||
fprintf(stderr, "SEGV_CODE %i", si->si_code);
|
if (expected_segv_code == 0 || expected_segv_code != si->si_code) {
|
||||||
|
fprintf(stderr, "received unexpected SEGV_CODE %i", si->si_code);
|
||||||
exit(139); // standard exit code for SIGSEGV
|
exit(139); // standard exit code for SIGSEGV
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
|
@ -7,36 +7,15 @@ import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
@RunWith(DeviceJUnit4ClassRunner.class)
|
@RunWith(DeviceJUnit4ClassRunner.class)
|
||||||
public class MemtagTest extends BaseHostJUnit4Test {
|
public class MemtagTest extends BaseHostJUnit4Test {
|
||||||
|
|
||||||
private static final String TEST_BINARY = "/data/local/tmp/memtag_test";
|
private static final String TEST_BINARY = "/data/local/tmp/memtag_test";
|
||||||
|
|
||||||
enum Result {
|
private void runTest(String name) throws DeviceNotAvailableException {
|
||||||
SUCCESS(0, ""),
|
|
||||||
// it's expected that the device is configured to use asymm MTE tag checking mode
|
|
||||||
ASYNC_MTE_ERROR(139, "SEGV_CODE 8"),
|
|
||||||
SYNC_MTE_ERROR(139, "SEGV_CODE 9"),
|
|
||||||
;
|
|
||||||
|
|
||||||
public final int exitCode;
|
|
||||||
public final String stderr;
|
|
||||||
|
|
||||||
Result(int exitCode, String stderr) {
|
|
||||||
this.exitCode = exitCode;
|
|
||||||
this.stderr = stderr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int SEGV_EXIT_CODE = 139;
|
|
||||||
|
|
||||||
private void runTest(String name, Result expectedResult) throws DeviceNotAvailableException {
|
|
||||||
var args = new ArrayList<String>();
|
var args = new ArrayList<String>();
|
||||||
args.add(TEST_BINARY);
|
args.add(TEST_BINARY);
|
||||||
args.add(name);
|
args.add(name);
|
||||||
|
@ -44,52 +23,52 @@ public class MemtagTest extends BaseHostJUnit4Test {
|
||||||
|
|
||||||
var result = getDevice().executeShellV2Command(cmdLine);
|
var result = getDevice().executeShellV2Command(cmdLine);
|
||||||
|
|
||||||
assertEquals("process exit code", expectedResult.exitCode, result.getExitCode().intValue());
|
assertEquals("stderr", "", result.getStderr());
|
||||||
assertEquals("stderr", expectedResult.stderr, result.getStderr());
|
assertEquals("process exit code", 0, result.getExitCode().intValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void tag_distinctness() throws DeviceNotAvailableException {
|
public void tag_distinctness() throws DeviceNotAvailableException {
|
||||||
runTest("tag_distinctness", Result.SUCCESS);
|
runTest("tag_distinctness");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void read_after_free() throws DeviceNotAvailableException {
|
public void read_after_free() throws DeviceNotAvailableException {
|
||||||
runTest("read_after_free", Result.SYNC_MTE_ERROR);
|
runTest("read_after_free");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void write_after_free() throws DeviceNotAvailableException {
|
public void write_after_free() throws DeviceNotAvailableException {
|
||||||
runTest("write_after_free", Result.ASYNC_MTE_ERROR);
|
runTest("write_after_free");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void underflow_read() throws DeviceNotAvailableException {
|
public void underflow_read() throws DeviceNotAvailableException {
|
||||||
runTest("underflow_read", Result.SYNC_MTE_ERROR);
|
runTest("underflow_read");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void underflow_write() throws DeviceNotAvailableException {
|
public void underflow_write() throws DeviceNotAvailableException {
|
||||||
runTest("underflow_write", Result.ASYNC_MTE_ERROR);
|
runTest("underflow_write");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void overflow_read() throws DeviceNotAvailableException {
|
public void overflow_read() throws DeviceNotAvailableException {
|
||||||
runTest("overflow_read", Result.SYNC_MTE_ERROR);
|
runTest("overflow_read");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void overflow_write() throws DeviceNotAvailableException {
|
public void overflow_write() throws DeviceNotAvailableException {
|
||||||
runTest("overflow_write", Result.ASYNC_MTE_ERROR);
|
runTest("overflow_write");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void untagged_read() throws DeviceNotAvailableException {
|
public void untagged_read() throws DeviceNotAvailableException {
|
||||||
runTest("untagged_read", Result.SYNC_MTE_ERROR);
|
runTest("untagged_read");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void untagged_write() throws DeviceNotAvailableException {
|
public void untagged_write() throws DeviceNotAvailableException {
|
||||||
runTest("untagged_write", Result.ASYNC_MTE_ERROR);
|
runTest("untagged_write");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue