diff --git a/services/modules/seccomp/BUILD.gn b/services/modules/seccomp/BUILD.gn index 7b2874b1d1beffd01fc6a8ad508b9f6a2e65996a..3b9b641874d76033bf0a01e913a20cf3c3ba3e2e 100755 --- a/services/modules/seccomp/BUILD.gn +++ b/services/modules/seccomp/BUILD.gn @@ -107,6 +107,7 @@ ohos_prebuilt_seccomp("updater_filter") { filtername = "updater" process_type = "system" + uid_is_root = true part_name = INIT_PART subsystem_name = "startup" diff --git a/services/modules/seccomp/scripts/generate_code_from_policy.py b/services/modules/seccomp/scripts/generate_code_from_policy.py index 2436f7337e4257474005f7870eb46421e963cb72..3a92887c757f9c2e2537c3bc0e7bedbbaf86f959 100755 --- a/services/modules/seccomp/scripts/generate_code_from_policy.py +++ b/services/modules/seccomp/scripts/generate_code_from_policy.py @@ -101,6 +101,15 @@ def is_function_name_exist(arch, function_name, func_name_nr_table): raise ValidateError('{} not exsit in {} function_name_nr_table Table'.format(function_name, arch)) +def is_function_name_repeats(func_name, allow_list_with_args): + for line in allow_list_with_args: + pos = line.find(':') + function_name = line[:pos] + if func_name == function_name: + return True + return False + + def function_name_to_nr(function_name_list, func_name_nr_table): return set(func_name_nr_table[function_name] for function_name \ in function_name_list if function_name in func_name_nr_table) @@ -292,6 +301,9 @@ class SeccompPolicyParam: priority_function_name_list_with_args self.final_allow_list_with_args |= self.allow_list_with_args self.final_priority_with_args |= self.priority_with_args + for line in self.final_allow_list.copy(): + if is_function_name_repeats(line, self.final_allow_list_with_args): + self.final_allow_list.remove(line) self.clear_list() diff --git a/services/modules/seccomp/scripts/seccomp_policy_fixer.gni b/services/modules/seccomp/scripts/seccomp_policy_fixer.gni index 3fb413c6c795d5628d425f02c12bf3a1a7f5d369..d7600452327b62607adfc04b65b0fe09bc5ef048 100755 --- a/services/modules/seccomp/scripts/seccomp_policy_fixer.gni +++ b/services/modules/seccomp/scripts/seccomp_policy_fixer.gni @@ -86,6 +86,17 @@ template("ohos_prebuilt_seccomp") { sources += get_target_outputs(":${_syscall_to_nr_arm_name}") sources += get_target_outputs(":${_syscall_to_nr_arm64_name}") + uid_is_root = false + if (defined(invoker.uid_is_root)) { + uid_is_root = invoker.uid_is_root + } else { + uid_is_root = false + } + if (invoker.process_type == "system" && invoker.filtername != "appspawn" && + invoker.filtername != "nwebspawn" && uid_is_root == false) { + sources += [ "//base/startup/init/services/modules/seccomp/seccomp_policy/system_uid_filter.seccomp.policy" ] + } + deps = [ ":${_syscall_to_nr_arm64_name}", ":${_syscall_to_nr_arm_name}", diff --git a/services/modules/seccomp/seccomp_policy/system_uid_filter.seccomp.policy b/services/modules/seccomp/seccomp_policy/system_uid_filter.seccomp.policy new file mode 100644 index 0000000000000000000000000000000000000000..fccd497660c44c9ae093d5def41952398fb24f49 --- /dev/null +++ b/services/modules/seccomp/seccomp_policy/system_uid_filter.seccomp.policy @@ -0,0 +1,27 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# 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. + +# For now, it supports architechture of ['arm', 'arm64']. + +@returnValue +TRAP + +@allowListWithArgs +setuid: if arg0 != 0; return ALLOW; else return TRAP;all +setreuid: if arg0 != 0 && arg1 != 0; return ALLOW; else return TRAP;all +setfsuid: if arg0 != 0; return ALLOW; else return TRAP;all +setresuid: if arg0 != 0 && arg1 != 0 && arg2 != 0; return ALLOW; else return TRAP;all +setuid32: if arg0 != 0; return ALLOW; else return TRAP;arm +setreuid32: if arg0 != 0 && arg1 != 0; return ALLOW; else return TRAP;arm +setfsuid32: if arg0 != 0; return ALLOW; else return TRAP;arm +setresuid32: if arg0 != 0 && arg1 != 0 && arg2 != 0; return ALLOW; else return TRAP;arm \ No newline at end of file diff --git a/test/unittest/seccomp/seccomp_unittest.cpp b/test/unittest/seccomp/seccomp_unittest.cpp index 25245f87a0c5a5dce7022e3729e7b70e0edd2ac7..4b27bbcbc839e583b540f7da44cf116942f347b9 100644 --- a/test/unittest/seccomp/seccomp_unittest.cpp +++ b/test/unittest/seccomp/seccomp_unittest.cpp @@ -215,6 +215,166 @@ public: return false; } + static bool CheckSetuid64ForUidFilter1() + { + int uid = syscall(__NR_setuid, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetuid64ForUidFilter2() + { + int uid = syscall(__NR_setuid, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetreuid64ForUidFilter1() + { + int uid = syscall(__NR_setreuid, 0, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetreuid64ForUidFilter2() + { + int uid = syscall(__NR_setreuid, 2, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetreuid64ForUidFilter3() + { + int uid = syscall(__NR_setreuid, 0, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetreuid64ForUidFilter4() + { + int uid = syscall(__NR_setreuid, 2, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetfsuid64ForUidFilter1() + { + int uid = syscall(__NR_setfsuid, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetfsuid64ForUidFilter2() + { + int uid = syscall(__NR_setfsuid, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid64ForUidFilter1() + { + int uid = syscall(__NR_setresuid, 0, 0, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid64ForUidFilter2() + { + int uid = syscall(__NR_setresuid, 2, 0, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid64ForUidFilter3() + { + int uid = syscall(__NR_setresuid, 0, 2, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid64ForUidFilter4() + { + int uid = syscall(__NR_setresuid, 0, 0, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid64ForUidFilter5() + { + int uid = syscall(__NR_setresuid, 0, 2, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid64ForUidFilter6() + { + int uid = syscall(__NR_setresuid, 2, 0, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid64ForUidFilter7() + { + int uid = syscall(__NR_setresuid, 2, 2, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid64ForUidFilter8() + { + int uid = syscall(__NR_setresuid, 2, 2, 2); + if (uid == 0) { + return true; + } + + return false; + } + void TestSystemSycall() { // system blocklist @@ -224,6 +384,55 @@ public: // system allowlist ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckGetpid, true); EXPECT_EQ(ret, 0); + + // system_uid_filter_test + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetuid64ForUidFilter1, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetuid64ForUidFilter2, true); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetreuid64ForUidFilter1, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetreuid64ForUidFilter2, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetreuid64ForUidFilter3, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetreuid64ForUidFilter4, true); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetfsuid64ForUidFilter1, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetfsuid64ForUidFilter2, true); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid64ForUidFilter1, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid64ForUidFilter2, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid64ForUidFilter3, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid64ForUidFilter4, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid64ForUidFilter5, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid64ForUidFilter6, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid64ForUidFilter7, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid64ForUidFilter8, true); + EXPECT_EQ(ret, 0); } void TestSetUidGidFilter() @@ -296,6 +505,326 @@ public: return false; } + static bool CheckSetuid32ForUidFilter1() + { + int uid = syscall(__NR_setuid32, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetuid32ForUidFilter2() + { + int uid = syscall(__NR_setuid32, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetuid16ForUidFilter1() + { + int uid = syscall(__NR_setuid, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetuid16ForUidFilter2() + { + int uid = syscall(__NR_setuid, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetreuid32ForUidFilter1() + { + int uid = syscall(__NR_setreuid32, 0, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetreuid32ForUidFilter2() + { + int uid = syscall(__NR_setreuid32, 2, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetreuid32ForUidFilter3() + { + int uid = syscall(__NR_setreuid32, 0, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetreuid32ForUidFilter4() + { + int uid = syscall(__NR_setreuid32, 2, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetreuid16ForUidFilter1() + { + int uid = syscall(__NR_setreuid, 0, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetreuid16ForUidFilter2() + { + int uid = syscall(__NR_setreuid, 2, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetreuid16ForUidFilter3() + { + int uid = syscall(__NR_setreuid, 0, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetreuid16ForUidFilter4() + { + int uid = syscall(__NR_setreuid, 2, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetfsuid32ForUidFilter1() + { + int uid = syscall(__NR_setfsuid32, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetfsuid32ForUidFilter2() + { + int uid = syscall(__NR_setfsuid32, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetfsuid16ForUidFilter1() + { + int uid = syscall(__NR_setfsuid, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetfsuid16ForUidFilter2() + { + int uid = syscall(__NR_setfsuid, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid32ForUidFilter1() + { + int uid = syscall(__NR_setresuid32, 0, 0, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid32ForUidFilter2() + { + int uid = syscall(__NR_setresuid32, 2, 0, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid32ForUidFilter3() + { + int uid = syscall(__NR_setresuid32, 0, 2, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid32ForUidFilter4() + { + int uid = syscall(__NR_setresuid32, 0, 0, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid32ForUidFilter5() + { + int uid = syscall(__NR_setresuid32, 0, 2, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid32ForUidFilter6() + { + int uid = syscall(__NR_setresuid32, 2, 0, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid32ForUidFilter7() + { + int uid = syscall(__NR_setresuid32, 2, 2, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid32ForUidFilter8() + { + int uid = syscall(__NR_setresuid32, 2, 2, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid16ForUidFilter1() + { + int uid = syscall(__NR_setresuid, 0, 0, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid16ForUidFilter2() + { + int uid = syscall(__NR_setresuid, 2, 0, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid16ForUidFilter3() + { + int uid = syscall(__NR_setresuid, 0, 2, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid16ForUidFilter4() + { + int uid = syscall(__NR_setresuid, 0, 0, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid16ForUidFilter5() + { + int uid = syscall(__NR_setresuid, 0, 2, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid16ForUidFilter6() + { + int uid = syscall(__NR_setresuid, 2, 0, 2); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid16ForUidFilter7() + { + int uid = syscall(__NR_setresuid, 2, 2, 0); + if (uid == 0) { + return true; + } + + return false; + } + + static bool CheckSetresuid16ForUidFilter8() + { + int uid = syscall(__NR_setresuid, 2, 2, 2); + if (uid == 0) { + return true; + } + + return false; + } + void TestSystemSycall() { // system blocklist @@ -305,6 +834,103 @@ public: // system allowlist ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckGetuid32, true); EXPECT_EQ(ret, 0); + + // system_uid_filter_test + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetuid32ForUidFilter1, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetuid32ForUidFilter2, true); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetuid16ForUidFilter1, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetuid16ForUidFilter2, true); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetreuid32ForUidFilter1, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetreuid32ForUidFilter2, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetreuid32ForUidFilter3, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetreuid32ForUidFilter4, true); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetreuid16ForUidFilter1, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetreuid16ForUidFilter2, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetreuid16ForUidFilter3, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetreuid16ForUidFilter4, true); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetfsuid32ForUidFilter1, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetfsuid32ForUidFilter2, true); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetfsuid16ForUidFilter1, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetfsuid16ForUidFilter2, true); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid32ForUidFilter1, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid32ForUidFilter2, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid32ForUidFilter3, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid32ForUidFilter4, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid32ForUidFilter5, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid32ForUidFilter6, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid32ForUidFilter7, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid32ForUidFilter8, true); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid16ForUidFilter1, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid16ForUidFilter2, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid16ForUidFilter3, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid16ForUidFilter4, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid16ForUidFilter5, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid16ForUidFilter6, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid16ForUidFilter7, false); + EXPECT_EQ(ret, 0); + + ret = CheckSyscall(SYSTEM_SA, SYSTEM_NAME, CheckSetresuid16ForUidFilter8, true); + EXPECT_EQ(ret, 0); } void TestSetUidGidFilter()