linux kernel seccomp

 

_set_seccomp_filter调用flow

frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

634  static void SetUpSeccompFilter(uid_t uid, bool is_child_zygote) {
635    if (!gIsSecurityEnforced) {
636      ALOGI("seccomp disabled by setenforce 0");
637      return;
638    }
639  
640    // Apply system or app filter based on uid.
641    if (uid >= AID_APP_START) {
642      if (is_child_zygote) {
643        set_app_zygote_seccomp_filter();
644      } else {
645        set_app_seccomp_filter();
646      }
647    } else {
648      set_system_seccomp_filter();
649    }
650  }

 

bionic/libc/seccomp/seccomp_policy.cpp

273  bool set_app_seccomp_filter() {
274      return _set_seccomp_filter(FilterType::APP);
275  }
276  
277  bool set_app_zygote_seccomp_filter() {
278      return _set_seccomp_filter(FilterType::APP_ZYGOTE);
279  }
280  
281  bool set_system_seccomp_filter() {
282      return _set_seccomp_filter(FilterType::SYSTEM);
283  }

 

 

215  bool _set_seccomp_filter(FilterType type) {
216      const sock_filter *p, *s;
217      size_t p_size, s_size;
218      filter f;
219  
220      switch (type) {
221        case APP:
222          p = primary_app_filter;
223          p_size = primary_app_filter_size;
224          s = secondary_app_filter;
225          s_size = secondary_app_filter_size;
226          break;
227        case APP_ZYGOTE:
228          p = primary_app_zygote_filter;
229          p_size = primary_app_zygote_filter_size;
230          s = secondary_app_zygote_filter;
231          s_size = secondary_app_zygote_filter_size;
232          break;
233        case SYSTEM:
234          p = primary_system_filter;
235          p_size = primary_system_filter_size;
236          s = secondary_system_filter;
237          s_size = secondary_system_filter_size;
238          break;
239      }
270      return install_filter(f);

 

172  static bool install_filter(filter const& f) {
173      struct sock_fprog prog = {
174          static_cast<unsigned short>(f.size()),
175          const_cast<struct sock_filter*>(&f[0]),
176      };
177      // This assumes either the current process has CAP_SYS_ADMIN, or PR_SET_NO_NEW_PRIVS bit is set.
178      if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0) {
179          PLOG(FATAL) << "Could not set seccomp filter of size " << f.size();
180          return false;
181      }
182      return true;
183  }

通过prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER)给进程设置自定义seccomp rule

seccomp有如下几种,如果是MODE_STRICT,则只允许read、write、sigreturn、exit这4个系统调用,使用其他系统调用会终止程序(会被发送SIGKILL kill),很明显一个程序不可能只使用4个系统调用,因为这种限制可用性不大后面就有了可以自由设置禁用系统调用的方式设置arg2为SECCOMP_MODE_FILTER(2),这样可以通过arg3参数自由设置可以使用的系统调用:

24  #define SECCOMP_MODE_STRICT 1
25  #define SECCOMP_MODE_FILTER 2

 

上面的primary_app_filter根据目标架构,如果是arm64,则它对应arm64_app_filter,这个数组定义的地方为自动生成的,在如下生成的cpp文件里:

arm64_app_filter variable definition

./out/soong/.intermediates/bionic/libc/libseccomp_policy_app_sources/android_arm64_armv8-a_cortex-a73/gen/arm64_app_policy.cpp
./out/soong/.intermediates/bionic/libc/libseccomp_policy_app_sources/android_arm_armv8-a_cortex-a73/gen/arm64_app_policy.cpp

 

const sock_filter arm64_system_filter[] = {
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 38),

BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 98, 36, 0), //futex

BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 29, 35, 0), //ioctl

BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 220, 17, 0),

BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 101, 9, 0),

BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 43, 5, 0),

BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 30, 3, 0),

BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),

BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 18, 30, 29), //io_setup|io_destroy|io_submit|io_cancel|io_getevents|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|getcwd

 

 

*bionic/libc/seccomp/seccomp_policy.cpp、arm64_app_policy.cpp是被编译到system/lib/libandroid_runtime.so

 

posted @ 2022-12-29 20:25  aspirs  阅读(328)  评论(0编辑  收藏  举报