blob: e8de7837ae28a2ad7b1d2d76a11373654660bd6e [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.os.cts;
import junit.framework.TestCase;
public class SeccompTest extends TestCase {
static {
System.loadLibrary("ctsos_jni");
}
public void testSeccomp() {
if (CpuFeatures.isArm64Cpu() || CpuFeatures.isArm64CpuIn32BitMode()) {
return; // seccomp not yet supported on arm64
}
if (OSFeatures.needsSeccompSupport()) {
assertTrue("Please enable seccomp support "
+ "in your kernel (CONFIG_SECCOMP_FILTER=y)",
OSFeatures.hasSeccompSupport());
}
}
public void testKernelBasicTests() {
if (!OSFeatures.needsSeccompSupport())
return;
final String[] tests = {
"global.mode_strict_support",
"global.mode_strict_cannot_call_prctl",
"global.no_new_privs_support",
"global.mode_filter_support",
/* "global.mode_filter_without_nnp", // all Android processes already have nnp */
"global.filter_size_limits",
"global.filter_chain_limits",
"global.mode_filter_cannot_move_to_strict",
"global.mode_filter_get_seccomp",
"global.ALLOW_all",
"global.empty_prog",
"global.unknown_ret_is_kill_inside",
"global.unknown_ret_is_kill_above_allow",
"global.KILL_all",
"global.KILL_one",
"global.KILL_one_arg_one",
"global.KILL_one_arg_six",
"global.arg_out_of_range",
"global.ERRNO_one",
"global.ERRNO_one_ok",
};
runKernelUnitTestSuite(tests);
}
public void testKernelTrapTests() {
if (!OSFeatures.needsSeccompSupport())
return;
final String[] tests = {
"TRAP.dfl",
"TRAP.ign",
"TRAP.handler",
};
runKernelUnitTestSuite(tests);
}
public void testKernelPrecedenceTests() {
if (!OSFeatures.needsSeccompSupport())
return;
final String[] tests = {
"precedence.allow_ok",
"precedence.kill_is_highest",
"precedence.kill_is_highest_in_any_order",
"precedence.trap_is_second",
"precedence.trap_is_second_in_any_order",
"precedence.errno_is_third",
"precedence.errno_is_third_in_any_order",
"precedence.trace_is_fourth",
"precedence.trace_is_fourth_in_any_order",
};
runKernelUnitTestSuite(tests);
}
/* // The SECCOMP_RET_TRACE does not work under Android Arm32.
public void testKernelTraceTests() {
if (!OSFeatures.needsSeccompSupport())
return;
final String[] tests = {
"TRACE_poke.read_has_side_effects",
"TRACE_poke.getpid_runs_normally",
"TRACE_syscall.syscall_allowed",
"TRACE_syscall.syscall_redirected",
"TRACE_syscall.syscall_dropped",
};
runKernelUnitTestSuite(tests);
}
*/
public void testKernelTSYNCTests() {
if (!OSFeatures.needsSeccompSupport())
return;
final String[] tests = {
"global.seccomp_syscall",
"global.seccomp_syscall_mode_lock",
"global.TSYNC_first",
"TSYNC.siblings_fail_prctl",
"TSYNC.two_siblings_with_ancestor",
/* "TSYNC.two_sibling_want_nnp", // all Android processes already have nnp */
"TSYNC.two_siblings_with_no_filter",
"TSYNC.two_siblings_with_one_divergence",
"TSYNC.two_siblings_not_under_filter",
/* "global.syscall_restart", // ptrace attach fails */
};
runKernelUnitTestSuite(tests);
}
/**
* Runs a kernel unit test suite (an array of kernel test names).
*/
private void runKernelUnitTestSuite(final String[] tests) {
for (final String test : tests) {
// TODO: Replace the URL with the documentation when it's finished.
assertTrue(test + " failed. This test requires kernel functionality to pass. "
+ "Please go to http://XXXXX for instructions on how to enable or "
+ "backport the required functionality.",
runKernelUnitTest(test));
}
}
/**
* Runs the seccomp_bpf_unittest of the given name.
*/
private native boolean runKernelUnitTest(final String name);
}