github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/executor/android/android_seccomp.h (about)

     1  // Copyright 2020 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  // These headers are generated by the Android build system and need to be updated periodically.
     5  
     6  // Header files are generated by `genseccomp.py`
     7  // (https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/tools/genseccomp.py).
     8  // Arguments are taken from the android build file
     9  // (https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/Android.bp).
    10  #if GOARCH_arm64
    11  #define PRIMARY_ARCH AUDIT_ARCH_AARCH64
    12  #include "arm64_app_policy.h"
    13  static const struct sock_filter* primary_app_filter = arm64_app_filter;
    14  static const size_t primary_app_filter_size = arm64_app_filter_size;
    15  #include "arm64_system_policy.h"
    16  static const struct sock_filter* system_filter = arm64_system_filter;
    17  static const size_t system_filter_size = arm64_system_filter_size;
    18  // We need 3 for ValidateArchitecture and 1 for ExamineSyscall and 4 for ValidateArchitectureAndJumpIfNeeded + 2 extra Disallow
    19  #define kFilterMaxSize (arm64_app_filter_size + 3 + 1 + 4 + 2)
    20  
    21  #elif GOARCH_arm
    22  #define PRIMARY_ARCH AUDIT_ARCH_ARM
    23  #include "arm_app_policy.h"
    24  static const struct sock_filter* primary_app_filter = arm_app_filter;
    25  static const size_t primary_app_filter_size = arm_app_filter_size;
    26  #include "arm_system_policy.h"
    27  static const struct sock_filter* system_filter = arm_system_filter;
    28  static const size_t system_filter_size = arm_system_filter_size;
    29  #define kFilterMaxSize (arm_app_filter_size + 3 + 1 + 4 + 2)
    30  
    31  // Note: clone3() and set/get_robust_list() are added as they are used
    32  // by pthread_create().
    33  #elif GOARCH_amd64
    34  #define PRIMARY_ARCH AUDIT_ARCH_X86_64
    35  #include "x86_64_app_policy.h"
    36  static const struct sock_filter* primary_app_filter = x86_64_app_filter;
    37  static const size_t primary_app_filter_size = x86_64_app_filter_size;
    38  #include "x86_64_system_policy.h"
    39  static const struct sock_filter* system_filter = x86_64_system_filter;
    40  static const size_t system_filter_size = x86_64_system_filter_size;
    41  #define kFilterMaxSize (x86_64_app_filter_size + 3 + 1 + 4 + 2)
    42  
    43  #elif GOARCH_386
    44  #define PRIMARY_ARCH AUDIT_ARCH_I386
    45  #include "x86_app_policy.h"
    46  static const struct sock_filter* primary_app_filter = x86_app_filter;
    47  static const size_t primary_app_filter_size = x86_app_filter_size;
    48  #include "x86_system_policy.h"
    49  static const struct sock_filter* system_filter = x86_system_filter;
    50  static const size_t system_filter_size = x86_system_filter_size;
    51  #define kFilterMaxSize (x86_app_filter_size + 3 + 1 + 4 + 2)
    52  
    53  #else
    54  #error No architecture was defined!
    55  #endif
    56  
    57  #define syscall_nr (offsetof(struct seccomp_data, nr))
    58  #define arch_nr (offsetof(struct seccomp_data, arch))
    59  
    60  typedef struct Filter_t {
    61  	struct sock_filter data[kFilterMaxSize];
    62  	size_t count;
    63  } Filter;
    64  
    65  static void push_back(Filter* filter_array, struct sock_filter filter)
    66  {
    67  	if (filter_array->count == kFilterMaxSize)
    68  		failmsg("can't add another syscall to seccomp filter", "count=%zu", filter_array->count);
    69  	filter_array->data[filter_array->count++] = filter;
    70  }
    71  
    72  static void Disallow(Filter* f)
    73  {
    74  	struct sock_filter filter = BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRAP);
    75  	push_back(f, filter);
    76  }
    77  
    78  static void ExamineSyscall(Filter* f)
    79  {
    80  	struct sock_filter filter = BPF_STMT(BPF_LD | BPF_W | BPF_ABS, syscall_nr);
    81  	push_back(f, filter);
    82  }
    83  
    84  static void ValidateArchitecture(Filter* f)
    85  {
    86  	struct sock_filter filter1 = BPF_STMT(BPF_LD | BPF_W | BPF_ABS, arch_nr);
    87  	struct sock_filter filter2 = BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, PRIMARY_ARCH, 1, 0);
    88  	push_back(f, filter1);
    89  	push_back(f, filter2);
    90  	Disallow(f);
    91  }
    92  
    93  // Modified from the orignal Android code to fail instead of return.
    94  static void install_filter(const Filter* f)
    95  {
    96  	struct sock_fprog prog = {
    97  	    (unsigned short)f->count,
    98  	    (struct sock_filter*)&f->data[0],
    99  	};
   100  	// This assumes either the current process has CAP_SYS_ADMIN, or PR_SET_NO_NEW_PRIVS bit is set.
   101  	if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0)
   102  		failmsg("could not set seccomp filter", "size=%zu", f->count);
   103  }
   104  
   105  // Modified from the original Android code as we don't need dual arch support
   106  static void set_seccomp_filter(const struct sock_filter* filter, size_t size)
   107  {
   108  	Filter f;
   109  	f.count = 0;
   110  	ValidateArchitecture(&f);
   111  	ExamineSyscall(&f);
   112  
   113  	for (size_t i = 0; i < size; ++i)
   114  		push_back(&f, filter[i]);
   115  	Disallow(&f);
   116  
   117  	// Will fail() if anything fails.
   118  	install_filter(&f);
   119  }
   120  
   121  enum {
   122  	SCFS_RestrictedApp,
   123  	SCFS_SystemAccount
   124  };
   125  
   126  static void set_app_seccomp_filter(int account)
   127  {
   128  	if (account == SCFS_SystemAccount) {
   129  		set_seccomp_filter(system_filter, system_filter_size);
   130  	} else {
   131  		set_seccomp_filter(primary_app_filter, primary_app_filter_size);
   132  	}
   133  }