]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
57183d11 LP |
2 | #pragma once |
3 | ||
7a8288f6 | 4 | #if HAVE_SECCOMP |
a60e9f7f | 5 | #include <seccomp.h> |
65a57927 | 6 | #endif |
f6281133 | 7 | #include <stdbool.h> |
a8fbdf54 | 8 | #include <stdint.h> |
57183d11 | 9 | |
005bfaf1 | 10 | #include "errno-list.h" |
3c098014 | 11 | #include "errno-util.h" |
005bfaf1 | 12 | #include "parse-util.h" |
469830d1 | 13 | #include "set.h" |
005bfaf1 | 14 | #include "string-util.h" |
469830d1 | 15 | |
65a57927 LP |
16 | #if HAVE_SECCOMP |
17 | ||
57183d11 LP |
18 | const char* seccomp_arch_to_string(uint32_t c); |
19 | int seccomp_arch_from_string(const char *n, uint32_t *ret); | |
e9642be2 | 20 | |
469830d1 | 21 | int seccomp_init_for_arch(scmp_filter_ctx *ret, uint32_t arch, uint32_t default_action); |
201c1cc2 | 22 | |
83f12b27 FS |
23 | bool is_seccomp_available(void); |
24 | ||
8130926d LP |
25 | typedef struct SyscallFilterSet { |
26 | const char *name; | |
d5efc18b | 27 | const char *help; |
201c1cc2 | 28 | const char *value; |
8130926d LP |
29 | } SyscallFilterSet; |
30 | ||
31 | enum { | |
95aac012 | 32 | /* Please leave DEFAULT first and KNOWN last, but sort the rest alphabetically */ |
40eb6a80 | 33 | SYSCALL_FILTER_SET_DEFAULT, |
44898c53 | 34 | SYSCALL_FILTER_SET_AIO, |
133ddbbe | 35 | SYSCALL_FILTER_SET_BASIC_IO, |
44898c53 | 36 | SYSCALL_FILTER_SET_CHOWN, |
8130926d LP |
37 | SYSCALL_FILTER_SET_CLOCK, |
38 | SYSCALL_FILTER_SET_CPU_EMULATION, | |
39 | SYSCALL_FILTER_SET_DEBUG, | |
1a1b13c9 | 40 | SYSCALL_FILTER_SET_FILE_SYSTEM, |
8130926d LP |
41 | SYSCALL_FILTER_SET_IO_EVENT, |
42 | SYSCALL_FILTER_SET_IPC, | |
43 | SYSCALL_FILTER_SET_KEYRING, | |
cd0ddf6f | 44 | SYSCALL_FILTER_SET_MEMLOCK, |
8130926d LP |
45 | SYSCALL_FILTER_SET_MODULE, |
46 | SYSCALL_FILTER_SET_MOUNT, | |
47 | SYSCALL_FILTER_SET_NETWORK_IO, | |
48 | SYSCALL_FILTER_SET_OBSOLETE, | |
9493b168 | 49 | SYSCALL_FILTER_SET_PKEY, |
8130926d LP |
50 | SYSCALL_FILTER_SET_PRIVILEGED, |
51 | SYSCALL_FILTER_SET_PROCESS, | |
52 | SYSCALL_FILTER_SET_RAW_IO, | |
bd2ab3f4 | 53 | SYSCALL_FILTER_SET_REBOOT, |
133ddbbe | 54 | SYSCALL_FILTER_SET_RESOURCES, |
d12632a8 | 55 | SYSCALL_FILTER_SET_SANDBOX, |
6eaaeee9 | 56 | SYSCALL_FILTER_SET_SETUID, |
cd0ddf6f | 57 | SYSCALL_FILTER_SET_SIGNAL, |
bd2ab3f4 | 58 | SYSCALL_FILTER_SET_SWAP, |
44898c53 | 59 | SYSCALL_FILTER_SET_SYNC, |
70526841 | 60 | SYSCALL_FILTER_SET_SYSTEM_SERVICE, |
cd0ddf6f | 61 | SYSCALL_FILTER_SET_TIMER, |
95aac012 | 62 | SYSCALL_FILTER_SET_KNOWN, |
50524bd8 | 63 | _SYSCALL_FILTER_SET_MAX, |
8130926d LP |
64 | }; |
65 | ||
50524bd8 LP |
66 | assert_cc(SYSCALL_FILTER_SET_DEFAULT == 0); |
67 | assert_cc(SYSCALL_FILTER_SET_KNOWN == _SYSCALL_FILTER_SET_MAX-1); | |
68 | ||
8130926d LP |
69 | extern const SyscallFilterSet syscall_filter_sets[]; |
70 | ||
71 | const SyscallFilterSet *syscall_filter_set_find(const char *name); | |
72 | ||
8cfa775f | 73 | int seccomp_filter_set_add(Hashmap *s, bool b, const SyscallFilterSet *set); |
165a31c0 | 74 | |
000c0520 ZJS |
75 | int seccomp_add_syscall_filter_item( |
76 | scmp_filter_ctx *ctx, | |
77 | const char *name, | |
78 | uint32_t action, | |
79 | char **exclude, | |
80 | bool log_missing, | |
81 | char ***added); | |
69b1b241 | 82 | |
b54f36c6 ZJS |
83 | int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action, bool log_missing); |
84 | int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action, bool log_missing); | |
add00535 | 85 | |
13d92c63 | 86 | typedef enum SeccompParseFlags { |
ef31828d | 87 | SECCOMP_PARSE_INVERT = 1 << 0, |
6b000af4 | 88 | SECCOMP_PARSE_ALLOW_LIST = 1 << 1, |
ef31828d LP |
89 | SECCOMP_PARSE_LOG = 1 << 2, |
90 | SECCOMP_PARSE_PERMISSIVE = 1 << 3, | |
13d92c63 LP |
91 | } SeccompParseFlags; |
92 | ||
58f6ab44 ZJS |
93 | int seccomp_parse_syscall_filter( |
94 | const char *name, | |
95 | int errno_num, | |
96 | Hashmap *filter, | |
97 | SeccompParseFlags flags, | |
98 | const char *unit, | |
99 | const char *filename, unsigned line); | |
898748d8 | 100 | |
469830d1 | 101 | int seccomp_restrict_archs(Set *archs); |
add00535 | 102 | int seccomp_restrict_namespaces(unsigned long retain); |
469830d1 | 103 | int seccomp_protect_sysctl(void); |
620dbdd2 | 104 | int seccomp_protect_syslog(void); |
6b000af4 | 105 | int seccomp_restrict_address_families(Set *address_families, bool allow_list); |
a9002749 YW |
106 | int seccomp_restrict_realtime_full(int error_code); /* This is mostly for testing code. */ |
107 | static inline int seccomp_restrict_realtime(void) { | |
108 | return seccomp_restrict_realtime_full(EPERM); | |
109 | } | |
469830d1 | 110 | int seccomp_memory_deny_write_execute(void); |
78e864e5 | 111 | int seccomp_lock_personality(unsigned long personality); |
aecd5ac6 | 112 | int seccomp_protect_hostname(void); |
3c27973b | 113 | int seccomp_restrict_suid_sgid(void); |
469830d1 | 114 | |
65976868 GDF |
115 | extern uint32_t seccomp_local_archs[]; |
116 | ||
117 | #define SECCOMP_LOCAL_ARCH_END UINT32_MAX | |
118 | ||
119 | /* Note: 0 is safe to use here because although SCMP_ARCH_NATIVE is 0, it would | |
120 | * never be in the seccomp_local_archs array anyway so we can use it as a | |
121 | * marker. */ | |
122 | #define SECCOMP_LOCAL_ARCH_BLOCKED 0 | |
469830d1 LP |
123 | |
124 | #define SECCOMP_FOREACH_LOCAL_ARCH(arch) \ | |
125 | for (unsigned _i = ({ (arch) = seccomp_local_archs[0]; 0; }); \ | |
65976868 GDF |
126 | (arch) != SECCOMP_LOCAL_ARCH_END; \ |
127 | (arch) = seccomp_local_archs[++_i]) \ | |
128 | if ((arch) != SECCOMP_LOCAL_ARCH_BLOCKED) | |
469830d1 | 129 | |
7bc5e0b1 AZ |
130 | /* EACCES: does not have the CAP_SYS_ADMIN or no_new_privs == 1 |
131 | * ENOMEM: out of memory, failed to allocate space for a libseccomp structure, or would exceed a defined constant | |
132 | * EFAULT: addresses passed as args (by libseccomp) are invalid */ | |
3c098014 ZJS |
133 | static inline bool ERRNO_IS_NEG_SECCOMP_FATAL(intmax_t r) { |
134 | return IN_SET(r, | |
135 | -EPERM, | |
136 | -EACCES, | |
137 | -ENOMEM, | |
138 | -EFAULT); | |
139 | } | |
140 | _DEFINE_ABS_WRAPPER(SECCOMP_FATAL); | |
7bc5e0b1 | 141 | |
fd421c4a | 142 | DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(scmp_filter_ctx, seccomp_release, NULL); |
b16bd535 | 143 | |
de7fef4b | 144 | int parse_syscall_archs(char **l, Set **ret_archs); |
915fb324 LP |
145 | |
146 | uint32_t scmp_act_kill_process(void); | |
005bfaf1 | 147 | |
65a57927 LP |
148 | int parse_syscall_and_errno(const char *in, char **name, int *error); |
149 | ||
150 | int seccomp_suppress_sync(void); | |
151 | ||
152 | #else | |
153 | ||
154 | static inline bool is_seccomp_available(void) { | |
155 | return false; | |
156 | } | |
157 | ||
158 | #endif | |
159 | ||
005bfaf1 TM |
160 | /* This is a special value to be used where syscall filters otherwise expect errno numbers, will be |
161 | replaced with real seccomp action. */ | |
162 | enum { | |
163 | SECCOMP_ERROR_NUMBER_KILL = INT_MAX - 1, | |
164 | }; | |
165 | ||
166 | static inline bool seccomp_errno_or_action_is_valid(int n) { | |
167 | return n == SECCOMP_ERROR_NUMBER_KILL || errno_is_valid(n); | |
168 | } | |
169 | ||
170 | static inline int seccomp_parse_errno_or_action(const char *p) { | |
171 | if (streq_ptr(p, "kill")) | |
172 | return SECCOMP_ERROR_NUMBER_KILL; | |
173 | return parse_errno(p); | |
174 | } | |
175 | ||
176 | static inline const char *seccomp_errno_or_action_to_string(int num) { | |
177 | if (num == SECCOMP_ERROR_NUMBER_KILL) | |
178 | return "kill"; | |
179 | return errno_to_name(num); | |
180 | } |