1
/* filter engine-based seccomp system call filtering
3
* This program is free software; you can redistribute it and/or modify
4
* it under the terms of the GNU General Public License as published by
5
* the Free Software Foundation; either version 2 of the License, or
6
* (at your option) any later version.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program; if not, write to the Free Software
15
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
* Copyright (C) 2011 The Chromium OS Authors <chromium-os-dev@chromium.org>
20
#include <linux/compat.h>
21
#include <linux/err.h>
22
#include <linux/errno.h>
23
#include <linux/ftrace_event.h>
24
#include <linux/kallsyms.h>
25
#include <linux/kref.h>
26
#include <linux/perf_event.h>
27
#include <linux/prctl.h>
28
#include <linux/seccomp.h>
29
#include <linux/seq_file.h>
30
#include <linux/sched.h>
31
#include <linux/slab.h>
32
#include <linux/uaccess.h>
34
#include <asm/syscall.h>
35
#include <trace/syscall.h>
37
/* Pull in *just* to access event_filter->filter_string. */
38
#include "trace/trace.h"
40
#define SECCOMP_MAX_FILTER_LENGTH MAX_FILTER_STR_VAL
42
#define SECCOMP_FILTER_ALLOW "1"
43
#define SECCOMP_ACTION_DENY 0xffff
44
#define SECCOMP_ACTION_ALLOW 0xfffe
47
* struct seccomp_filters - container for seccomp filters
49
* @usage: reference count to manage the object lifetime.
50
* get/put helpers should be used when accessing an instance
51
* outside of a lifetime-guarded section. In general, this
52
* is only needed for handling shared filters across tasks.
53
* @flags: anonymous struct to wrap filters-specific flags
54
* @syscalls: array of 16-bit indices into @event_filters by syscall_nr
55
* May also be SECCOMP_ACTION_DENY or SECCOMP_ACTION_ALLOW
56
* @count: size of @event_filters
57
* @event_filters: array of pointers to ftrace event filters
59
* seccomp_filters objects should never be modified after being attached
62
struct seccomp_filters {
68
uint16_t syscalls[NR_syscalls];
70
struct event_filter *event_filters[0];
73
/* Make sure we can get to the syscall metadata that ftrace hordes. */
74
extern struct syscall_metadata *__start_syscalls_metadata[];
75
extern struct syscall_metadata *__stop_syscalls_metadata[];
77
static struct syscall_metadata **syscalls_metadata;
78
static struct syscall_metadata *syscall_nr_to_meta(int nr)
80
if (!syscalls_metadata || nr >= NR_syscalls || nr < 0)
83
return syscalls_metadata[nr];
87
* Make ftrace support optional
90
#if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PERF_EVENTS)
92
/* Fix up buffer creation to allow the ftrace filter engine to
93
* work with seccomp filter events.
94
* Lifted from kernel/trace/trace_syscalls.c
97
#ifndef ARCH_HAS_SYSCALL_MATCH_SYM_NAME
98
static inline bool arch_syscall_match_sym_name(const char *sym, const char *name)
101
* Only compare after the "sys" prefix. Archs that use
102
* syscall wrappers may have syscalls symbols aliases prefixed
103
* with "SyS" instead of "sys", leading to an unwanted
106
return !strcmp(sym + 3, name + 3);
110
static __init struct syscall_metadata *
111
find_syscall_meta(unsigned long syscall)
113
struct syscall_metadata **start;
114
struct syscall_metadata **stop;
115
char str[KSYM_SYMBOL_LEN];
118
start = __start_syscalls_metadata;
119
stop = __stop_syscalls_metadata;
120
kallsyms_lookup(syscall, NULL, NULL, NULL, str);
122
if (arch_syscall_match_sym_name(str, "sys_ni_syscall"))
125
for ( ; start < stop; start++) {
126
if ((*start)->name && arch_syscall_match_sym_name(str, (*start)->name))
132
int __init init_seccomp_filter(void)
134
struct syscall_metadata *meta;
138
syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
139
NR_syscalls, GFP_KERNEL);
140
if (!syscalls_metadata) {
145
for (i = 0; i < NR_syscalls; i++) {
146
addr = arch_syscall_addr(i);
147
meta = find_syscall_meta(addr);
151
meta->syscall_nr = i;
152
syscalls_metadata[i] = meta;
157
core_initcall(init_seccomp_filter);
160
* End of the ftrace metadata access fixup.
164
static int create_event_filter(struct event_filter **filter,
169
struct perf_event event;
171
ret = ftrace_profile_set_filter(&event, event_type, filter_string);
174
*filter = event.filter;
175
(*filter)->filter_string = kstrdup(filter_string, GFP_KERNEL);
176
if (!(*filter)->filter_string) {
177
ftrace_profile_free_filter(&event);
184
static char *get_filter_string(struct event_filter *filter)
187
return filter->filter_string;
191
static void free_event_filter(struct event_filter *filter)
193
struct perf_event event;
196
event.filter = filter;
197
ftrace_profile_free_filter(&event);
200
/* ftrace_syscall_enter_state_size - returns the state size required.
202
* @nb_args: number of system call args expected.
203
* a negative value implies the maximum allowed.
205
static size_t ftrace_syscall_enter_state_size(int nb_args)
207
/* syscall_get_arguments only supports up to 6 arguments. */
208
int arg_count = (nb_args >= 0 ? nb_args : 6);
209
size_t size = (sizeof(unsigned long) * arg_count) +
210
sizeof(struct syscall_trace_enter);
211
size = ALIGN(size + sizeof(u32), sizeof(u64));
216
#if 0 /* If we need exit interception. */
217
static size_t ftrace_syscall_exit_state_size(void)
219
return ALIGN(sizeof(struct syscall_trace_exit) + sizeof(u32),
220
sizeof(u64)) - sizeof(u32);
224
/* ftrace_syscall_enter_state - build state for filter matching
226
* @buf: buffer to populate with current task state for matching
227
* @available: size available for use in the buffer.
228
* @entry: optional pointer to the trace_entry member of the state.
230
* Returns 0 on success and non-zero otherwise.
231
* If @entry is NULL, it will be ignored.
233
static int ftrace_syscall_enter_state(u8 *buf, size_t available,
234
struct trace_entry **entry)
236
struct syscall_trace_enter *sys_enter;
237
struct syscall_metadata *sys_data;
240
struct pt_regs *regs = task_pt_regs(current);
242
syscall_nr = syscall_get_nr(current, regs);
246
sys_data = syscall_nr_to_meta(syscall_nr);
250
/* Determine the actual size needed. */
251
size = ftrace_syscall_enter_state_size(sys_data->nb_args);
252
BUG_ON(size > available);
253
sys_enter = (struct syscall_trace_enter *)buf;
255
/* Populating the struct trace_sys_enter is left to the caller, but
256
* a pointer is returned to encourage opacity.
259
*entry = &sys_enter->ent;
261
sys_enter->nr = syscall_nr;
262
syscall_get_arguments(current, regs, 0, sys_data->nb_args,
267
#else /* defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PERF_EVENTS) */
269
#define create_event_filter(_ef_pptr, _event_type, _str) (-ENOSYS)
270
#define get_filter_string(_ef) (NULL)
271
#define free_event_filter(_f) do { } while (0)
276
* seccomp_filters_alloc - allocates a new filters object
277
* @count: count to allocate for the event_filters array
279
* Returns ERR_PTR on error or an allocated object.
281
static struct seccomp_filters *seccomp_filters_alloc(uint16_t count)
283
struct seccomp_filters *f;
285
if (count >= SECCOMP_ACTION_ALLOW)
286
return ERR_PTR(-EINVAL);
288
f = kzalloc(sizeof(struct seccomp_filters) +
289
(count * sizeof(struct event_filter *)), GFP_KERNEL);
291
return ERR_PTR(-ENOMEM);
293
/* Lazy SECCOMP_ACTION_DENY assignment. */
294
memset(f->syscalls, 0xff, sizeof(f->syscalls));
295
kref_init(&f->usage);
305
* seccomp_filters_free - cleans up the filter list and frees the table
306
* @filters: NULL or live object to be completely destructed.
308
static void seccomp_filters_free(struct seccomp_filters *filters)
313
while (count < filters->count) {
314
struct event_filter *f = filters->event_filters[count];
315
free_event_filter(f);
321
static void __put_seccomp_filters(struct kref *kref)
323
struct seccomp_filters *orig =
324
container_of(kref, struct seccomp_filters, usage);
325
seccomp_filters_free(orig);
328
#define seccomp_filter_allow(_id) ((_id) == SECCOMP_ACTION_ALLOW)
329
#define seccomp_filter_deny(_id) ((_id) == SECCOMP_ACTION_DENY)
330
#define seccomp_filter_dynamic(_id) \
331
(!seccomp_filter_allow(_id) && !seccomp_filter_deny(_id))
332
static inline uint16_t seccomp_filter_id(const struct seccomp_filters *f,
336
return SECCOMP_ACTION_DENY;
337
return f->syscalls[syscall_nr];
340
static inline struct event_filter *seccomp_dynamic_filter(
341
const struct seccomp_filters *filters, uint16_t id)
343
if (!seccomp_filter_dynamic(id))
345
return filters->event_filters[id];
348
static inline void set_seccomp_filter_id(struct seccomp_filters *filters,
349
int syscall_nr, uint16_t id)
351
filters->syscalls[syscall_nr] = id;
354
static inline void set_seccomp_filter(struct seccomp_filters *filters,
355
int syscall_nr, uint16_t id,
356
struct event_filter *dynamic_filter)
358
filters->syscalls[syscall_nr] = id;
359
if (seccomp_filter_dynamic(id))
360
filters->event_filters[id] = dynamic_filter;
363
static struct event_filter *alloc_event_filter(int syscall_nr,
366
struct syscall_metadata *data;
367
struct event_filter *filter = NULL;
370
data = syscall_nr_to_meta(syscall_nr);
371
/* Argument-based filtering only works on ftrace-hooked syscalls. */
375
err = create_event_filter(&filter,
376
data->enter_event->event.type,
388
* seccomp_filters_copy - copies filters from src to dst.
390
* @dst: seccomp_filters to populate.
391
* @src: table to read from.
392
* @skip: specifies an entry, by system call, to skip.
394
* Returns non-zero on failure.
395
* Both the source and the destination should have no simultaneous
396
* writers, and dst should be exclusive to the caller.
397
* If @skip is < 0, it is ignored.
399
static int seccomp_filters_copy(struct seccomp_filters *dst,
400
const struct seccomp_filters *src,
403
int id = 0, ret = 0, nr;
404
memcpy(&dst->flags, &src->flags, sizeof(src->flags));
405
memcpy(dst->syscalls, src->syscalls, sizeof(dst->syscalls));
408
for (nr = 0; nr < NR_syscalls; ++nr) {
409
struct event_filter *filter;
411
uint16_t src_id = seccomp_filter_id(src, nr);
413
set_seccomp_filter(dst, nr, SECCOMP_ACTION_DENY,
417
if (!seccomp_filter_dynamic(src_id))
419
if (id >= dst->count) {
423
str = get_filter_string(seccomp_dynamic_filter(src, src_id));
424
filter = alloc_event_filter(nr, str);
425
if (IS_ERR(filter)) {
426
ret = PTR_ERR(filter);
429
set_seccomp_filter(dst, nr, id, filter);
438
* seccomp_extend_filter - appends more text to a syscall_nr's filter
439
* @filters: unattached filter object to operate on
440
* @syscall_nr: syscall number to update filters for
441
* @filter_string: string to append to the existing filter
443
* The new string will be &&'d to the original filter string to ensure that it
444
* always matches the existing predicates or less:
445
* (old_filter) && @filter_string
446
* A new seccomp_filters instance is returned on success and a ERR_PTR on
449
static int seccomp_extend_filter(struct seccomp_filters *filters,
450
int syscall_nr, char *filter_string)
452
struct event_filter *filter;
453
uint16_t id = seccomp_filter_id(filters, syscall_nr);
455
int ret = -EINVAL, expected;
457
/* No extending with a "1". */
458
if (!strcmp(SECCOMP_FILTER_ALLOW, filter_string))
461
/* ftrace events are not aware of CONFIG_COMPAT system calls and will
462
* use the incorrect argument metadata if enabled.
465
if (filters->flags.compat)
468
filter = seccomp_dynamic_filter(filters, id);
473
merged = kzalloc(SECCOMP_MAX_FILTER_LENGTH + 1, GFP_KERNEL);
478
/* Encapsulate the filter strings in parentheses to isolate operator
479
* precedence behavior.
481
expected = snprintf(merged, SECCOMP_MAX_FILTER_LENGTH, "(%s) && (%s)",
482
get_filter_string(filter), filter_string);
484
if (expected >= SECCOMP_MAX_FILTER_LENGTH || expected < 0)
487
/* Free the old filter */
488
free_event_filter(filter);
489
set_seccomp_filter(filters, syscall_nr, id, NULL);
492
filter = alloc_event_filter(syscall_nr, merged);
493
if (IS_ERR(filter)) {
494
ret = PTR_ERR(filter);
497
set_seccomp_filter(filters, syscall_nr, id, filter);
506
* seccomp_add_filter - adds a filter for an unfiltered syscall
507
* @filters: filters object to add a filter/action to
508
* @syscall_nr: system call number to add a filter for
509
* @filter_string: the filter string to apply
511
* Returns 0 on success and non-zero otherwise.
513
static int seccomp_add_filter(struct seccomp_filters *filters, int syscall_nr,
516
struct event_filter *filter;
519
if (!strcmp(SECCOMP_FILTER_ALLOW, filter_string)) {
520
set_seccomp_filter(filters, syscall_nr,
521
SECCOMP_ACTION_ALLOW, NULL);
525
/* ftrace events are not aware of CONFIG_COMPAT system calls and will
526
* use the incorrect argument metadata if enabled.
529
if (filters->flags.compat)
533
filter = alloc_event_filter(syscall_nr, filter_string);
534
if (IS_ERR(filter)) {
535
ret = PTR_ERR(filter);
538
/* Always add to the last slot available since additions are
539
* are only done one at a time.
541
set_seccomp_filter(filters, syscall_nr, filters->count - 1, filter);
546
/* Wrap optional ftrace syscall support. Returns 1 on match or 0 otherwise. */
547
static int filter_match_current(struct event_filter *event_filter)
550
#ifdef CONFIG_FTRACE_SYSCALLS
551
uint8_t syscall_state[64];
553
memset(syscall_state, 0, sizeof(syscall_state));
555
/* The generic tracing entry can remain zeroed. */
556
err = ftrace_syscall_enter_state(syscall_state, sizeof(syscall_state),
561
err = filter_match_preds(event_filter, syscall_state);
566
static const char *syscall_nr_to_name(int syscall)
568
const char *syscall_name = "unknown";
569
struct syscall_metadata *data = syscall_nr_to_meta(syscall);
571
syscall_name = data->name;
575
/* Encodes translation from sys_enter events to system call numbers.
576
* Returns -ENOSYS when the event doesn't match a system call or if
577
* current is_compat_task(). ftrace has no awareness of CONFIG_COMPAT
580
static int event_to_syscall_nr(int event_id)
584
if (is_compat_task())
587
for (nr = 0; nr < NR_syscalls; ++nr) {
588
struct syscall_metadata *data = syscall_nr_to_meta(nr);
592
if (data->enter_event->event.type == event_id)
600
static void filters_set_compat(struct seccomp_filters *filters)
603
if (is_compat_task())
604
filters->flags.compat = 1;
608
static inline int filters_compat_mismatch(struct seccomp_filters *filters)
614
if (!!(is_compat_task()) != filters->flags.compat)
620
static inline int syscall_is_execve(int syscall)
622
int nr = __NR_execve;
624
if (is_compat_task())
625
nr = __NR_seccomp_execve_32;
627
return syscall == nr;
631
#define KSTK_EIP(x) 0L
634
void seccomp_filter_log_failure(int syscall)
636
pr_info("%s[%d]: system call %d (%s) blocked at 0x%lx\n",
637
current->comm, task_pid_nr(current), syscall,
638
syscall_nr_to_name(syscall), KSTK_EIP(current));
641
/* put_seccomp_filters - decrements the ref count of @orig and may free. */
642
void put_seccomp_filters(struct seccomp_filters *orig)
646
kref_put(&orig->usage, __put_seccomp_filters);
649
/* get_seccomp_filters - increments the reference count of @orig. */
650
struct seccomp_filters *get_seccomp_filters(struct seccomp_filters *orig)
654
/* XXX: kref needs overflow prevention support. */
655
kref_get(&orig->usage);
660
* seccomp_test_filters - tests 'current' against the given syscall
661
* @syscall: number of the system call to test
663
* Returns 0 on ok and non-zero on error/failure.
665
int seccomp_test_filters(int syscall)
668
struct event_filter *filter;
669
struct seccomp_filters *filters;
672
mutex_lock(¤t->seccomp.filters_guard);
673
/* No reference counting is done. filters_guard should protect the
674
* lifetime of any existing pointer below.
676
filters = current->seccomp.filters;
680
if (filters_compat_mismatch(filters)) {
681
pr_info("%s[%d]: seccomp_filter compat() mismatch.\n",
682
current->comm, task_pid_nr(current));
686
/* execve is never allowed. */
687
if (syscall_is_execve(syscall))
691
id = seccomp_filter_id(filters, syscall);
692
if (seccomp_filter_allow(id))
696
if (!seccomp_filter_dynamic(id))
699
filter = seccomp_dynamic_filter(filters, id);
700
if (filter && filter_match_current(filter))
703
mutex_unlock(¤t->seccomp.filters_guard);
708
* seccomp_show_filters - prints the current filter state to a seq_file
709
* @filters: properly get()'d filters object
710
* @m: the prepared seq_file to receive the data
712
* Returns 0 on a successful write.
714
int seccomp_show_filters(struct seccomp_filters *filters, struct seq_file *m)
720
for (syscall = 0; syscall < NR_syscalls; ++syscall) {
721
uint16_t id = seccomp_filter_id(filters, syscall);
722
const char *filter_string = SECCOMP_FILTER_ALLOW;
723
if (seccomp_filter_deny(id))
725
seq_printf(m, "%d (%s): ",
727
syscall_nr_to_name(syscall));
728
if (seccomp_filter_dynamic(id))
729
filter_string = get_filter_string(
730
seccomp_dynamic_filter(filters, id));
731
seq_printf(m, "%s\n", filter_string);
736
EXPORT_SYMBOL_GPL(seccomp_show_filters);
739
* seccomp_get_filter - copies the filter_string into "buf"
740
* @syscall_nr: system call number to look up
741
* @buf: destination buffer
742
* @bufsize: available space in the buffer.
744
* Context: User context only. This function may sleep on allocation and
745
* operates on current. current must be attempting a system call
746
* when this is called.
748
* Looks up the filter for the given system call number on current. If found,
749
* the string length of the NUL-terminated buffer is returned and < 0 is
750
* returned on error. The NUL byte is not included in the length.
752
long seccomp_get_filter(int syscall_nr, char *buf, unsigned long bufsize)
754
struct seccomp_filters *filters;
755
struct event_filter *filter;
759
if (bufsize > SECCOMP_MAX_FILTER_LENGTH)
760
bufsize = SECCOMP_MAX_FILTER_LENGTH;
762
mutex_lock(¤t->seccomp.filters_guard);
763
filters = current->seccomp.filters;
769
id = seccomp_filter_id(filters, syscall_nr);
770
if (seccomp_filter_deny(id))
773
if (seccomp_filter_allow(id)) {
774
ret = strlcpy(buf, SECCOMP_FILTER_ALLOW, bufsize);
778
filter = seccomp_dynamic_filter(filters, id);
781
ret = strlcpy(buf, get_filter_string(filter), bufsize);
784
if (ret >= bufsize) {
789
mutex_unlock(¤t->seccomp.filters_guard);
792
EXPORT_SYMBOL_GPL(seccomp_get_filter);
795
* seccomp_clear_filter: clears the seccomp filter for a syscall.
796
* @syscall_nr: the system call number to clear filters for.
798
* Context: User context only. This function may sleep on allocation and
799
* operates on current. current must be attempting a system call
800
* when this is called.
802
* Returns 0 on success.
804
long seccomp_clear_filter(int syscall_nr)
806
struct seccomp_filters *filters = NULL, *orig_filters;
810
mutex_lock(¤t->seccomp.filters_guard);
811
orig_filters = current->seccomp.filters;
816
if (filters_compat_mismatch(orig_filters))
819
id = seccomp_filter_id(orig_filters, syscall_nr);
820
if (seccomp_filter_deny(id))
823
/* Create a new filters object for the task */
824
if (seccomp_filter_dynamic(id))
825
filters = seccomp_filters_alloc(orig_filters->count - 1);
827
filters = seccomp_filters_alloc(orig_filters->count);
829
if (IS_ERR(filters)) {
830
ret = PTR_ERR(filters);
834
/* Copy, but drop the requested entry. */
835
ret = seccomp_filters_copy(filters, orig_filters, syscall_nr);
838
get_seccomp_filters(filters); /* simplify the out: path */
840
current->seccomp.filters = filters;
841
put_seccomp_filters(orig_filters); /* for the task */
843
put_seccomp_filters(filters); /* for the extra get */
844
mutex_unlock(¤t->seccomp.filters_guard);
847
EXPORT_SYMBOL_GPL(seccomp_clear_filter);
850
* seccomp_set_filter: - Adds/extends a seccomp filter for a syscall.
851
* @syscall_nr: system call number to apply the filter to.
852
* @filter: ftrace filter string to apply.
854
* Context: User context only. This function may sleep on allocation and
855
* operates on current. current must be attempting a system call
856
* when this is called.
858
* New filters may be added for system calls when the current task is
859
* not in a secure computing mode (seccomp). Otherwise, existing filters may
862
* Returns 0 on success or an errno on failure.
864
long seccomp_set_filter(int syscall_nr, char *filter)
866
struct seccomp_filters *filters = NULL, *orig_filters = NULL;
869
uint16_t filters_needed;
871
mutex_lock(¤t->seccomp.filters_guard);
875
filter = strstrip(filter);
876
/* Disallow empty strings. */
880
orig_filters = current->seccomp.filters;
882
/* After the first call, compatibility mode is selected permanently. */
884
if (filters_compat_mismatch(orig_filters))
887
filters_needed = orig_filters ? orig_filters->count : 0;
888
id = seccomp_filter_id(orig_filters, syscall_nr);
889
if (seccomp_filter_deny(id)) {
890
/* Don't allow DENYs to be changed when in a seccomp mode */
892
if (current->seccomp.mode)
897
filters = seccomp_filters_alloc(filters_needed);
898
if (IS_ERR(filters)) {
899
ret = PTR_ERR(filters);
903
filters_set_compat(filters);
905
ret = seccomp_filters_copy(filters, orig_filters, -1);
910
if (seccomp_filter_deny(id))
911
ret = seccomp_add_filter(filters, syscall_nr, filter);
913
ret = seccomp_extend_filter(filters, syscall_nr, filter);
916
get_seccomp_filters(filters); /* simplify the error paths */
918
current->seccomp.filters = filters;
919
put_seccomp_filters(orig_filters); /* for the task */
921
put_seccomp_filters(filters); /* for get or task, on err */
922
mutex_unlock(¤t->seccomp.filters_guard);
925
EXPORT_SYMBOL_GPL(seccomp_set_filter);
927
long prctl_set_seccomp_filter(unsigned long id_type,
929
char __user *user_filter)
936
if (id_type != PR_SECCOMP_FILTER_EVENT &&
937
id_type != PR_SECCOMP_FILTER_SYSCALL)
940
if (id > (unsigned long) INT_MAX)
944
if (id_type == PR_SECCOMP_FILTER_EVENT)
945
nr = event_to_syscall_nr(nr);
952
if (nr >= NR_syscalls)
959
filter = kzalloc(SECCOMP_MAX_FILTER_LENGTH + 1, GFP_KERNEL);
965
if (strncpy_from_user(filter, user_filter,
966
SECCOMP_MAX_FILTER_LENGTH - 1) < 0)
969
ret = seccomp_set_filter(nr, filter);
976
long prctl_clear_seccomp_filter(unsigned long id_type, unsigned long id)
981
if (id_type != PR_SECCOMP_FILTER_EVENT &&
982
id_type != PR_SECCOMP_FILTER_SYSCALL)
985
if (id > (unsigned long) INT_MAX)
989
if (id_type == PR_SECCOMP_FILTER_EVENT)
990
nr = event_to_syscall_nr(nr);
997
if (nr >= NR_syscalls)
1000
ret = seccomp_clear_filter(nr);
1006
long prctl_get_seccomp_filter(unsigned long id_type, unsigned long id,
1007
char __user *dst, unsigned long available)
1009
unsigned long copied;
1011
int nr, ret = -EINVAL;
1016
/* Ignore extra buffer space. */
1017
if (available > SECCOMP_MAX_FILTER_LENGTH)
1018
available = SECCOMP_MAX_FILTER_LENGTH;
1020
if (id_type != PR_SECCOMP_FILTER_EVENT &&
1021
id_type != PR_SECCOMP_FILTER_SYSCALL)
1024
if (id > (unsigned long) INT_MAX)
1028
if (id_type == PR_SECCOMP_FILTER_EVENT)
1029
nr = event_to_syscall_nr(nr);
1036
if (nr >= NR_syscalls)
1040
buf = kzalloc(available, GFP_KERNEL);
1044
ret = seccomp_get_filter(nr, buf, available);
1048
/* Include the NUL byte in the copy. */
1049
copied = copy_to_user(dst, buf, ret + 1);