diff --git a/interfaces/innerkits/seccomp/BUILD.gn b/interfaces/innerkits/seccomp/BUILD.gn index 3a4d0e7988577f313061c79633a1a90811b67e70..e18c1fbfd3ecbbca377499832abedcea83d27fb2 100755 --- a/interfaces/innerkits/seccomp/BUILD.gn +++ b/interfaces/innerkits/seccomp/BUILD.gn @@ -18,6 +18,12 @@ config("seccomp_public_config") { } if (defined(build_seccomp) && build_seccomp) { + if (build_variant == "root") { + seccomp_enable_debug = true + } else { + seccomp_enable_debug = false + } + ohos_shared_library("seccomp") { sources = [ "//base/startup/init/services/modules/seccomp/seccomp_policy.c" ] @@ -31,6 +37,15 @@ if (defined(build_seccomp) && build_seccomp) { "//third_party/bounds_checking_function/include", ] + if (seccomp_enable_debug) { + include_dirs += [ + "../../../services/include", + "../../../services/include/param", + ] + + defines = [ "WITH_SECCOMP_DEBUG" ] + } + deps = [ "//base/startup/init/interfaces/innerkits:libbegetutil", "//third_party/bounds_checking_function:libsec_shared", diff --git a/services/init/init_common_service.c b/services/init/init_common_service.c index d6eb39833fd71adaa960d8e8befe2db5d0810aae..48ddcf7e5a247378e3d32643cc7d91f8a4cc0fd2 100644 --- a/services/init/init_common_service.c +++ b/services/init/init_common_service.c @@ -73,7 +73,7 @@ static int SetAllAmbientCapability(void) static void SetSystemSeccompPolicy(const Service *service) { #ifdef WITH_SECCOMP - if (strncmp(APPSPAWN_NAME, service->name, strlen(APPSPAWN_NAME)) \ + if (strncmp(APPSPAWN_NAME, service->name, strlen(APPSPAWN_NAME)) && strncmp(NWEBSPAWN_NAME, service->name, strlen(NWEBSPAWN_NAME)) && !strncmp(SA_MAIN_PATH, service->pathArgs.argv[0], strlen(SA_MAIN_PATH))) { PluginExecCmdByName("SetSeccompPolicy", "start"); diff --git a/services/modules/seccomp/BUILD.gn b/services/modules/seccomp/BUILD.gn index db241eb67e99914cecf64e23aa82fa1655cd1baf..f84bde36a8e4a52acaa693d1eb526441ac92e8ed 100755 --- a/services/modules/seccomp/BUILD.gn +++ b/services/modules/seccomp/BUILD.gn @@ -11,7 +11,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//base/startup/init/begetd.gni") import( "//base/startup/init/services/modules/seccomp/scripts/seccomp_policy_fixer.gni") import("//build/config/clang/clang.gni") @@ -20,6 +19,12 @@ import("//build/ohos/kernel/kernel.gni") INIT_PART = "init" +if (build_variant == "root") { + seccomp_enable_debug = true +} else { + seccomp_enable_debug = false +} + action("syscall_to_nr_arm") { script = "${clang_base_path}/bin/clang" output_dir = target_gen_dir + "/libsyscall_to_nr_arm" @@ -145,6 +150,15 @@ config("libseccomp_static_config") { "//base/startup/init/interfaces/innerkits/seccomp/include", "//third_party/bounds_checking_function/include", ] + + if (seccomp_enable_debug) { + include_dirs += [ + "../../../services/include", + "../../../services/include/param", + ] + + defines = [ "WITH_SECCOMP_DEBUG" ] + } } ohos_source_set("libseccomp_static") { diff --git a/services/modules/seccomp/scripts/generate_code_from_policy.py b/services/modules/seccomp/scripts/generate_code_from_policy.py index 37913d971cefd6f25b2ed062b7b6f303fa3bccb6..9cbe09813b2d7c27cbb747fbbed32eee02da8a9d 100755 --- a/services/modules/seccomp/scripts/generate_code_from_policy.py +++ b/services/modules/seccomp/scripts/generate_code_from_policy.py @@ -44,6 +44,7 @@ operation = ['<', '<=', '!=', '==', '>', '>=', '&'] ret_str_to_bpf = { 'KILL_PROCESS': 'SECCOMP_RET_KILL_PROCESS', 'KILL_THREAD': 'SECCOMP_RET_KILL_THREAD', + 'TRAP': 'SECCOMP_RET_TRAP', 'LOG' : 'SECCOMP_RET_LOG', 'ALLOW': 'SECCOMP_RET_ALLOW' } @@ -691,13 +692,13 @@ class GenBpfPolicy: bpf_policy.append(BPF_JEQ.format('AUDIT_ARCH_AARCH64', 3, 0)) bpf_policy.append(BPF_JEQ.format('AUDIT_ARCH_ARM', 0, 1)) bpf_policy.append(BPF_JA.format(skip_step)) - bpf_policy.append(BPF_RET_VALUE.format('SECCOMP_RET_KILL_PROCESS')) + bpf_policy.append(BPF_RET_VALUE.format('SECCOMP_RET_TRAP')) elif 'arm' in arches: bpf_policy.append(BPF_JEQ.format('AUDIT_ARCH_ARM', 1, 0)) - bpf_policy.append(BPF_RET_VALUE.format('SECCOMP_RET_KILL_PROCESS')) + bpf_policy.append(BPF_RET_VALUE.format('SECCOMP_RET_TRAP')) elif 'arm64' in arches: bpf_policy.append(BPF_JEQ.format('AUDIT_ARCH_AARCH64', 1, 0)) - bpf_policy.append(BPF_RET_VALUE.format('SECCOMP_RET_KILL_PROCESS')) + bpf_policy.append(BPF_RET_VALUE.format('SECCOMP_RET_TRAP')) else: self.bpf_policy = [] diff --git a/services/modules/seccomp/seccomp_policy.c b/services/modules/seccomp/seccomp_policy.c index 59bdae75266ab7baba7ef680ca2dfeb950018785..a89ba494d3d82f9efbfd2743fb63ac03fd2272ff 100644 --- a/services/modules/seccomp/seccomp_policy.c +++ b/services/modules/seccomp/seccomp_policy.c @@ -17,6 +17,11 @@ #include "plugin_adapter.h" #include "securec.h" +#ifdef WITH_SECCOMP_DEBUG +#include "init_utils.h" +#include "sys_param.h" +#endif + #include #include #include @@ -169,12 +174,34 @@ static int GetSeccompPolicy(const char *filterName, int **handler, return ret; } +#ifdef WITH_SECCOMP_DEBUG +static bool IsEnableSeccomp(void) +{ + char value[MAX_BUFFER_LEN] = {0}; + unsigned int len = MAX_BUFFER_LEN; + bool isEnableSeccompFlag = true; + if (SystemReadParam("persist.init.debug.seccomp.enable", value, &len) == 0) { + if (strncmp(value, "0", len) == 0) { + isEnableSeccompFlag = false; + } + } + + return isEnableSeccompFlag; +} +#endif + bool SetSeccompPolicyWithName(const char *filterName) { if (filterName == NULL) { return false; } +#ifdef WITH_SECCOMP_DEBUG + if (!IsEnableSeccomp()) { + return true; + } +#endif + void *handler = NULL; char *filterLibRealPath = NULL; struct sock_fprog prog; diff --git a/services/modules/seccomp/seccomp_policy/app_arm.seccomp.policy b/services/modules/seccomp/seccomp_policy/app_arm.seccomp.policy index cc91333124d9a7ee92ee31c7e9ba70cbb93abf6c..541d05d387d7f1bd2df570e0f026fc8ca57fc6a3 100644 --- a/services/modules/seccomp/seccomp_policy/app_arm.seccomp.policy +++ b/services/modules/seccomp/seccomp_policy/app_arm.seccomp.policy @@ -15,7 +15,7 @@ arm @returnValue -KILL_PROCESS +TRAP @priority ioctl diff --git a/services/modules/seccomp/seccomp_policy/app_arm64.seccomp.policy b/services/modules/seccomp/seccomp_policy/app_arm64.seccomp.policy index b52ec8f5dcd6f0c332fa9dd48271fc1868e46065..dbdbc57f3ab04b49630ec75278b9a43dc598900f 100644 --- a/services/modules/seccomp/seccomp_policy/app_arm64.seccomp.policy +++ b/services/modules/seccomp/seccomp_policy/app_arm64.seccomp.policy @@ -15,7 +15,7 @@ arm64 @returnValue -KILL_PROCESS +TRAP @priority ioctl diff --git a/services/modules/seccomp/seccomp_policy/renderer_arm.seccomp.policy b/services/modules/seccomp/seccomp_policy/renderer_arm.seccomp.policy index 638490a764e548993d014497ad3aae3b678663c8..400546f2810e66428b8f41a36f023c02eb5b3b56 100644 --- a/services/modules/seccomp/seccomp_policy/renderer_arm.seccomp.policy +++ b/services/modules/seccomp/seccomp_policy/renderer_arm.seccomp.policy @@ -15,7 +15,7 @@ arm @returnValue -KILL_PROCESS +TRAP @headFiles "time.h" @@ -175,9 +175,9 @@ ptrace membarrier @allowListWithArgs -getrusage:if arg0 == RUSAGE_SELF || arg0 == RUSAGE_THREAD; return ALLOW; else return KILL_PROCESS; -clock_getres:if arg0 >= CLOCK_REALTIME && arg0 <= CLOCK_BOOTTIME; return ALLOW; else return KILL_PROCESS; -clock_gettime:if arg0 >= CLOCK_REALTIME && arg0 <= CLOCK_BOOTTIME; return ALLOW; else return KILL_PROCESS; -clock_nanosleep:if arg0 >= CLOCK_REALTIME && arg0 <= CLOCK_BOOTTIME; return ALLOW; else return KILL_PROCESS; -socketpair:if arg0 == AF_UNIX; return ALLOW; else return KILL_PROCESS; -getsockopt:if arg1 == SOL_SOCKET || arg2 == SO_PEEK_OFF; return ALLOW; else return KILL_PROCESS; +getrusage:if arg0 == RUSAGE_SELF || arg0 == RUSAGE_THREAD; return ALLOW; else return TRAP; +clock_getres:if arg0 >= CLOCK_REALTIME && arg0 <= CLOCK_BOOTTIME; return ALLOW; else return TRAP; +clock_gettime:if arg0 >= CLOCK_REALTIME && arg0 <= CLOCK_BOOTTIME; return ALLOW; else return TRAP; +clock_nanosleep:if arg0 >= CLOCK_REALTIME && arg0 <= CLOCK_BOOTTIME; return ALLOW; else return TRAP; +socketpair:if arg0 == AF_UNIX; return ALLOW; else return TRAP; +getsockopt:if arg1 == SOL_SOCKET || arg2 == SO_PEEK_OFF; return ALLOW; else return TRAP; diff --git a/services/modules/seccomp/seccomp_policy/renderer_arm64.seccomp.policy b/services/modules/seccomp/seccomp_policy/renderer_arm64.seccomp.policy index a76d8341e7ea1ab56dab0e8b484742e402012909..d0e47ecff190cac26ca42167aa783f178b74fff6 100644 --- a/services/modules/seccomp/seccomp_policy/renderer_arm64.seccomp.policy +++ b/services/modules/seccomp/seccomp_policy/renderer_arm64.seccomp.policy @@ -15,7 +15,7 @@ arm64 @returnValue -KILL_PROCESS +TRAP @headFiles "time.h" @@ -144,9 +144,9 @@ ptrace membarrier @allowListWithArgs -getrusage:if arg0 == RUSAGE_SELF || arg0 == RUSAGE_THREAD; return ALLOW; else return KILL_PROCESS; -clock_getres:if arg0 >= CLOCK_REALTIME && arg0 <= CLOCK_BOOTTIME; return ALLOW; else return KILL_PROCESS; -clock_gettime:if arg0 >= CLOCK_REALTIME && arg0 <= CLOCK_BOOTTIME; return ALLOW; else return KILL_PROCESS; -clock_nanosleep:if arg0 >= CLOCK_REALTIME && arg0 <= CLOCK_BOOTTIME; return ALLOW; else return KILL_PROCESS; -socketpair:if arg0 == AF_UNIX; return ALLOW; else return KILL_PROCESS; -getsockopt:if arg1 == SOL_SOCKET || arg2 == SO_PEEK_OFF; return ALLOW; else return KILL_PROCESS; +getrusage:if arg0 == RUSAGE_SELF || arg0 == RUSAGE_THREAD; return ALLOW; else return TRAP; +clock_getres:if arg0 >= CLOCK_REALTIME && arg0 <= CLOCK_BOOTTIME; return ALLOW; else return TRAP; +clock_gettime:if arg0 >= CLOCK_REALTIME && arg0 <= CLOCK_BOOTTIME; return ALLOW; else return TRAP; +clock_nanosleep:if arg0 >= CLOCK_REALTIME && arg0 <= CLOCK_BOOTTIME; return ALLOW; else return TRAP; +socketpair:if arg0 == AF_UNIX; return ALLOW; else return TRAP; +getsockopt:if arg1 == SOL_SOCKET || arg2 == SO_PEEK_OFF; return ALLOW; else return TRAP; diff --git a/services/modules/seccomp/seccomp_policy/spawn_arm.seccomp.policy b/services/modules/seccomp/seccomp_policy/spawn_arm.seccomp.policy index 0b882f6087229e5d26b59eba558ffafd828ae44b..bb9445c4456cc7d53d8f24de7fb824f9d15f565a 100644 --- a/services/modules/seccomp/seccomp_policy/spawn_arm.seccomp.policy +++ b/services/modules/seccomp/seccomp_policy/spawn_arm.seccomp.policy @@ -15,11 +15,11 @@ arm @returnValue -KILL_PROCESS +TRAP @mode ONLY_CHECK_ARGS @allowListWithArgs -setresuid32: if arg0 >= 1000 && arg1 >= 1000 && arg2 >= 1000; return ALLOW; else return KILL_PROCESS; -setresgid32: if arg0 >= 1000 && arg1 >= 1000 && arg2 >= 1000; return ALLOW; else return KILL_PROCESS; +setresuid32: if arg0 >= 1000 && arg1 >= 1000 && arg2 >= 1000; return ALLOW; else return TRAP; +setresgid32: if arg0 >= 1000 && arg1 >= 1000 && arg2 >= 1000; return ALLOW; else return TRAP; diff --git a/services/modules/seccomp/seccomp_policy/spawn_arm64.seccomp.policy b/services/modules/seccomp/seccomp_policy/spawn_arm64.seccomp.policy index acf97888ca5b1603aec032bc2f18cfd8bb27c389..641f8775abe913ae6c7124a07baa86a5d81976e6 100644 --- a/services/modules/seccomp/seccomp_policy/spawn_arm64.seccomp.policy +++ b/services/modules/seccomp/seccomp_policy/spawn_arm64.seccomp.policy @@ -14,11 +14,11 @@ arm64 @returnValue -KILL_PROCESS +TRAP @mode ONLY_CHECK_ARGS @allowListWithArgs -setresuid: if arg0 >= 1000 && arg1 >= 1000 && arg2 >= 1000; return ALLOW; else return KILL_PROCESS; -setresgid: if arg0 >= 1000 && arg1 >= 1000 && arg2 >= 1000; return ALLOW; else return KILL_PROCESS; +setresuid: if arg0 >= 1000 && arg1 >= 1000 && arg2 >= 1000; return ALLOW; else return TRAP; +setresgid: if arg0 >= 1000 && arg1 >= 1000 && arg2 >= 1000; return ALLOW; else return TRAP; diff --git a/services/modules/seccomp/seccomp_policy/system_arm.seccomp.policy b/services/modules/seccomp/seccomp_policy/system_arm.seccomp.policy index 1b06803e7ca65364674b1f293e5d2b9e1ee3c535..4e475f6196386818e1e304ca2c85a5d8a9c3dc3c 100644 --- a/services/modules/seccomp/seccomp_policy/system_arm.seccomp.policy +++ b/services/modules/seccomp/seccomp_policy/system_arm.seccomp.policy @@ -15,7 +15,7 @@ arm @returnValue -KILL_PROCESS +TRAP @allowList restart_syscall diff --git a/services/modules/seccomp/seccomp_policy/system_arm64.seccomp.policy b/services/modules/seccomp/seccomp_policy/system_arm64.seccomp.policy index ed32068a7722390b60847bb2eb785b1bd643c0bb..ee5cc28b649f930e961065c2f66d54126ed4daf8 100644 --- a/services/modules/seccomp/seccomp_policy/system_arm64.seccomp.policy +++ b/services/modules/seccomp/seccomp_policy/system_arm64.seccomp.policy @@ -15,7 +15,7 @@ arm64 @returnValue -KILL_PROCESS +TRAP @allowList io_setup diff --git a/test/unittest/seccomp/seccomp_unittest.cpp b/test/unittest/seccomp/seccomp_unittest.cpp index 851170c216a49f7cbf73cdd050e597405b96bcb9..9a1c63a62a2cdb30ea3ff482fd999fc8849f366d 100644 --- a/test/unittest/seccomp/seccomp_unittest.cpp +++ b/test/unittest/seccomp/seccomp_unittest.cpp @@ -15,8 +15,6 @@ #include -#include - #include #include #include @@ -35,7 +33,8 @@ #include "seccomp_policy.h" using SyscallFunc = bool (*)(void); -constexpr int SLEEP_TIME = 100000; // 100ms +constexpr int SLEEP_TIME_100MS = 100000; // 100ms +constexpr int SLEEP_TIME_1S = 1; using namespace testing::ext; using namespace std; @@ -47,9 +46,20 @@ public: virtual ~SeccompUnitTest() {}; static void SetUpTestCase() {}; static void TearDownTestCase() {}; - void SetUp() {}; + + void SetUp() + { + /* + * Wait for 1 second to prevent the generated crash file + * from being overwritten because the crash interval is too short + * and the crash file's name is constructed by time stamp. + */ + sleep(SLEEP_TIME_1S); + }; + void TearDown() {}; void TestBody(void) {}; + static void Handler(int s) { } @@ -62,6 +72,7 @@ public: std::cout << "PR_SET_NO_NEW_PRIVS set fail " << std::endl; exit(EXIT_FAILURE); } + if (!SetSeccompPolicyWithName(filterName)) { std::cout << "SetSeccompPolicy set fail fiterName is " << filterName << std::endl; exit(EXIT_FAILURE); @@ -97,7 +108,7 @@ public: /* Sleeping for avoiding influencing child proccess wait for other threads * which were created by other unittests to release global rwlock. The global * rwlock will be used by function dlopen in child process */ - usleep(SLEEP_TIME); + usleep(SLEEP_TIME_100MS); pid = StartChild(filterName, func); if (pid == -1) { @@ -333,7 +344,7 @@ HWTEST_F(SeccompUnitTest, TestSystemSycall, TestSize.Level1) /** * @tc.name: TestSetUidGidFilter - * @tc.desc: Verify the system seccomp policy. + * @tc.desc: Verify the uid gid seccomp policy. * @tc.type: FUNC * @tc.require: issueI5IUWJ */ @@ -344,8 +355,8 @@ HWTEST_F(SeccompUnitTest, TestSetUidGidFilter, TestSize.Level1) } /** - * @tc.name: TestSystemSycall - * @tc.desc: Verify the system seccomp policy. + * @tc.name: TestAppSycall + * @tc.desc: Verify the app seccomp policy. * @tc.type: FUNC * @tc.require: issueI5MUXD */