4 * Copyright (c) 2012,2013 Red Hat <pmoore@redhat.com>
5 * Author: Paul Moore <paul@paul-moore.com>
9 * This library is free software; you can redistribute it and/or modify it
10 * under the terms of version 2.1 of the GNU Lesser General Public License as
11 * published by the Free Software Foundation.
13 * This library is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this library; if not, see <http://www.gnu.org/licenses>.
39 #define API __attribute__((visibility("default")))
41 const struct scmp_version library_version
= {
42 .major
= SCMP_VER_MAJOR
,
43 .minor
= SCMP_VER_MINOR
,
44 .micro
= SCMP_VER_MICRO
,
48 * Validate a filter context
49 * @param ctx the filter context
51 * Attempt to validate the provided filter context. Returns zero if the
52 * context is valid, negative values on failure.
55 static int _ctx_valid(const scmp_filter_ctx
*ctx
)
57 return db_col_valid((struct db_filter_col
*)ctx
);
61 * Validate a syscall number
62 * @param syscall the syscall number
64 * Attempt to perform basic syscall number validation. Returns zero of the
65 * syscall appears valid, negative values on failure.
68 static int _syscall_valid(int syscall
)
70 if (syscall
<= -1 && syscall
>= -99)
75 /* NOTE - function header comment in include/seccomp.h */
76 API
const struct scmp_version
*seccomp_version(void)
78 return &library_version
;
81 /* NOTE - function header comment in include/seccomp.h */
82 API scmp_filter_ctx
seccomp_init(uint32_t def_action
)
84 if (db_action_valid(def_action
) < 0)
87 return db_col_init(def_action
);
90 /* NOTE - function header comment in include/seccomp.h */
91 API
int seccomp_reset(scmp_filter_ctx ctx
, uint32_t def_action
)
93 struct db_filter_col
*col
= (struct db_filter_col
*)ctx
;
95 if (ctx
== NULL
|| db_action_valid(def_action
) < 0)
98 return db_col_reset(col
, def_action
);
101 /* NOTE - function header comment in include/seccomp.h */
102 API
void seccomp_release(scmp_filter_ctx ctx
)
104 db_col_release((struct db_filter_col
*)ctx
);
107 /* NOTE - function header comment in include/seccomp.h */
108 API
int seccomp_merge(scmp_filter_ctx ctx_dst
,
109 scmp_filter_ctx ctx_src
)
111 struct db_filter_col
*col_dst
= (struct db_filter_col
*)ctx_dst
;
112 struct db_filter_col
*col_src
= (struct db_filter_col
*)ctx_src
;
114 if (db_col_valid(col_dst
) || db_col_valid(col_src
))
117 /* NOTE: only the default action, NNP, and TSYNC settings must match */
118 if ((col_dst
->attr
.act_default
!= col_src
->attr
.act_default
) ||
119 (col_dst
->attr
.nnp_enable
!= col_src
->attr
.nnp_enable
) ||
120 (col_dst
->attr
.tsync_enable
!= col_src
->attr
.tsync_enable
))
123 return db_col_merge(col_dst
, col_src
);
126 /* NOTE - function header comment in include/seccomp.h */
127 API
uint32_t seccomp_arch_resolve_name(const char *arch_name
)
129 const struct arch_def
*arch
;
131 if (arch_name
== NULL
)
134 arch
= arch_def_lookup_name(arch_name
);
141 /* NOTE - function header comment in include/seccomp.h */
142 API
uint32_t seccomp_arch_native(void)
144 return arch_def_native
->token
;
147 /* NOTE - function header comment in include/seccomp.h */
148 API
int seccomp_arch_exist(const scmp_filter_ctx ctx
,
151 struct db_filter_col
*col
= (struct db_filter_col
*)ctx
;
154 arch_token
= arch_def_native
->token
;
156 if (arch_valid(arch_token
))
159 return (db_col_arch_exist(col
, arch_token
) ? 0 : -EEXIST
);
162 /* NOTE - function header comment in include/seccomp.h */
163 API
int seccomp_arch_add(scmp_filter_ctx ctx
, uint32_t arch_token
)
165 const struct arch_def
*arch
;
166 struct db_filter_col
*col
= (struct db_filter_col
*)ctx
;
169 arch_token
= arch_def_native
->token
;
171 if (arch_valid(arch_token
))
173 if (db_col_arch_exist(col
, arch_token
))
176 arch
= arch_def_lookup(arch_token
);
179 return db_col_db_new(col
, arch
);
182 /* NOTE - function header comment in include/seccomp.h */
183 API
int seccomp_arch_remove(scmp_filter_ctx ctx
, uint32_t arch_token
)
185 struct db_filter_col
*col
= (struct db_filter_col
*)ctx
;
188 arch_token
= arch_def_native
->token
;
190 if (arch_valid(arch_token
))
192 if (db_col_arch_exist(col
, arch_token
) != -EEXIST
)
195 return db_col_db_remove(col
, arch_token
);
198 /* NOTE - function header comment in include/seccomp.h */
199 API
int seccomp_load(const scmp_filter_ctx ctx
)
201 struct db_filter_col
*col
;
205 col
= (struct db_filter_col
*)ctx
;
207 return sys_filter_load(col
);
210 /* NOTE - function header comment in include/seccomp.h */
211 API
int seccomp_attr_get(const scmp_filter_ctx ctx
,
212 enum scmp_filter_attr attr
, uint32_t *value
)
217 return db_col_attr_get((const struct db_filter_col
*)ctx
, attr
, value
);
220 /* NOTE - function header comment in include/seccomp.h */
221 API
int seccomp_attr_set(scmp_filter_ctx ctx
,
222 enum scmp_filter_attr attr
, uint32_t value
)
227 return db_col_attr_set((struct db_filter_col
*)ctx
, attr
, value
);
230 /* NOTE - function header comment in include/seccomp.h */
231 API
char *seccomp_syscall_resolve_num_arch(uint32_t arch_token
, int num
)
233 const struct arch_def
*arch
;
237 arch_token
= arch_def_native
->token
;
238 if (arch_valid(arch_token
))
240 arch
= arch_def_lookup(arch_token
);
244 name
= arch_syscall_resolve_num(arch
, num
);
251 /* NOTE - function header comment in include/seccomp.h */
252 API
int seccomp_syscall_resolve_name_arch(uint32_t arch_token
, const char *name
)
254 const struct arch_def
*arch
;
257 return __NR_SCMP_ERROR
;
260 arch_token
= arch_def_native
->token
;
261 if (arch_valid(arch_token
))
262 return __NR_SCMP_ERROR
;
263 arch
= arch_def_lookup(arch_token
);
265 return __NR_SCMP_ERROR
;
267 return arch_syscall_resolve_name(arch
, name
);
270 /* NOTE - function header comment in include/seccomp.h */
271 API
int seccomp_syscall_resolve_name_rewrite(uint32_t arch_token
,
276 const struct arch_def
*arch
;
279 return __NR_SCMP_ERROR
;
282 arch_token
= arch_def_native
->token
;
283 if (arch_valid(arch_token
))
284 return __NR_SCMP_ERROR
;
285 arch
= arch_def_lookup(arch_token
);
287 return __NR_SCMP_ERROR
;
289 syscall
= arch_syscall_resolve_name(arch
, name
);
290 if (syscall
== __NR_SCMP_ERROR
)
291 return __NR_SCMP_ERROR
;
292 rc
= arch_syscall_rewrite(arch
, &syscall
);
294 /* if we can't rewrite the syscall, just pass it through */
297 return __NR_SCMP_ERROR
;
302 /* NOTE - function header comment in include/seccomp.h */
303 API
int seccomp_syscall_resolve_name(const char *name
)
305 return seccomp_syscall_resolve_name_arch(SCMP_ARCH_NATIVE
, name
);
308 /* NOTE - function header comment in include/seccomp.h */
309 API
int seccomp_syscall_priority(scmp_filter_ctx ctx
,
310 int syscall
, uint8_t priority
)
312 struct db_filter_col
*col
= (struct db_filter_col
*)ctx
;
314 if (db_col_valid(col
) || _syscall_valid(syscall
))
317 return db_col_syscall_priority(col
, syscall
, priority
);
320 /* NOTE - function header comment in include/seccomp.h */
321 API
int seccomp_rule_add_array(scmp_filter_ctx ctx
,
322 uint32_t action
, int syscall
,
323 unsigned int arg_cnt
,
324 const struct scmp_arg_cmp
*arg_array
)
327 struct db_filter_col
*col
= (struct db_filter_col
*)ctx
;
329 if (arg_cnt
> ARG_COUNT_MAX
)
331 if (arg_cnt
> 0 && arg_array
== NULL
)
334 if (db_col_valid(col
) || _syscall_valid(syscall
))
337 rc
= db_action_valid(action
);
340 if (action
== col
->attr
.act_default
)
343 return db_col_rule_add(col
, 0, action
, syscall
, arg_cnt
, arg_array
);
346 /* NOTE - function header comment in include/seccomp.h */
347 API
int seccomp_rule_add(scmp_filter_ctx ctx
,
348 uint32_t action
, int syscall
,
349 unsigned int arg_cnt
, ...)
353 struct scmp_arg_cmp arg_array
[ARG_COUNT_MAX
];
356 /* arg_cnt is unsigned, so no need to check the lower bound */
357 if (arg_cnt
> ARG_COUNT_MAX
)
360 va_start(arg_list
, arg_cnt
);
361 for (iter
= 0; iter
< arg_cnt
; ++iter
)
362 arg_array
[iter
] = va_arg(arg_list
, struct scmp_arg_cmp
);
363 rc
= seccomp_rule_add_array(ctx
, action
, syscall
, arg_cnt
, arg_array
);
369 /* NOTE - function header comment in include/seccomp.h */
370 API
int seccomp_rule_add_exact_array(scmp_filter_ctx ctx
,
371 uint32_t action
, int syscall
,
372 unsigned int arg_cnt
,
373 const struct scmp_arg_cmp
*arg_array
)
376 struct db_filter_col
*col
= (struct db_filter_col
*)ctx
;
378 if (arg_cnt
> ARG_COUNT_MAX
)
380 if (arg_cnt
> 0 && arg_array
== NULL
)
383 if (db_col_valid(col
) || _syscall_valid(syscall
))
386 rc
= db_action_valid(action
);
389 if (action
== col
->attr
.act_default
)
392 if (col
->filter_cnt
> 1)
395 return db_col_rule_add(col
, 1, action
, syscall
, arg_cnt
, arg_array
);
398 /* NOTE - function header comment in include/seccomp.h */
399 API
int seccomp_rule_add_exact(scmp_filter_ctx ctx
,
400 uint32_t action
, int syscall
,
401 unsigned int arg_cnt
, ...)
405 struct scmp_arg_cmp arg_array
[ARG_COUNT_MAX
];
408 /* arg_cnt is unsigned, so no need to check the lower bound */
409 if (arg_cnt
> ARG_COUNT_MAX
)
412 va_start(arg_list
, arg_cnt
);
413 for (iter
= 0; iter
< arg_cnt
; ++iter
)
414 arg_array
[iter
] = va_arg(arg_list
, struct scmp_arg_cmp
);
415 rc
= seccomp_rule_add_exact_array(ctx
,
416 action
, syscall
, arg_cnt
, arg_array
);
422 /* NOTE - function header comment in include/seccomp.h */
423 API
int seccomp_export_pfc(const scmp_filter_ctx ctx
, int fd
)
428 return gen_pfc_generate((struct db_filter_col
*)ctx
, fd
);
431 /* NOTE - function header comment in include/seccomp.h */
432 API
int seccomp_export_bpf(const scmp_filter_ctx ctx
, int fd
)
435 struct bpf_program
*program
;
440 program
= gen_bpf_generate((struct db_filter_col
*)ctx
);
443 rc
= write(fd
, program
->blks
, BPF_PGM_SIZE(program
));
444 gen_bpf_release(program
);